-- ----------------------------------------------------------------------- -- -- $Source: /repository/uni/htk/widgets/ScrollBar.hs,v $ -- -- HTk - a GUI toolkit for Haskell - (c) Universitaet Bremen -- -- $Revision: 1.5 $ from $Date: 2002/02/21 14:37:49 $ -- Last modification by $Author: cxl $ -- -- ----------------------------------------------------------------------- --- -- HTk's scrollbar widget.
-- -- A scroll bar is a widget which controls scrolling. -- module ScrollBar ( HasScroller(..), ScrollBar, newScrollBar, ScrollUnit(..), Slider(..), HasSlider(..), ScrollBarElem(..), activateScrollBarElem, getActivatedElem, Fraction, fraction, identify, setView ) where import Core import BaseClasses(Widget) import Configuration import Geometry import Resources import Destructible import Slider import Char import Computation import Synchronized import ReferenceVariables import Packer import Tooltip import GUIValue import List(dropWhile, takeWhile) import Char(isSpace) -- ----------------------------------------------------------------------- -- fraction type -- ----------------------------------------------------------------------- --- -- Fractions are floating point values between 0 and 1 representing -- relative positions within the scrolled range. type Fraction = Double --- -- Internal. instance GUIValue (Fraction, Fraction) where --- -- Internal. cdefault = (0.0, 0.0) --- -- Internal. instance Show (Fraction, Fraction) where --- -- Internal. showsPrec d (f1, f2) r = show f1 ++ " " ++ show f2 ++ r --- -- Internal. instance Read (Fraction, Fraction) where --- -- Internal. readsPrec p b = case readsPrec p b of [(x,xs)] -> case readsPrec p xs of [(y,ys)] -> [((x,y),ys)] _ -> [] _ -> [] -- ----------------------------------------------------------------------- -- classes -- ----------------------------------------------------------------------- --- -- Scrollable widgets instantiate class HasScroller. class Widget w => HasScroller w where --- -- True for widgets that are scrollable in the given -- orientation. isWfOrientation :: w -> Orientation -> Bool --- -- Associates a scrollbar with a scrollable widget. scrollbar :: Orientation -> ScrollBar -> Config w --- -- Positions the scrolled widget so the give Fraction is -- off-screen to the left. moveto :: Orientation -> w -> Fraction -> IO () --- -- Scrolls the associated widget by n pages or units (depending on the -- given ScrollUnit). scroll :: Orientation -> w -> Int -> ScrollUnit -> IO () --- -- Returns two fractions between 0 and 1 that describe the amount of -- the widget off-screen to the left and the amount of the widget visible. view :: Orientation -> w -> IO (Fraction, Fraction) isWfOrientation _ _ = True scrollbar Horizontal sc w | isWfOrientation w Horizontal = do cset sc "command" (TkCommand (varname w ++ " xview")) execTclScript [tkDeclScrollVar w] cset w "xscrollcommand" (TkCommand (varname sc ++ " set")) execTclScript [tkDeclScrollVar sc] return w scrollbar Vertical sc w | isWfOrientation w Vertical = do cset sc "command" (TkCommand (varname w ++ " yview")) execTclScript [tkDeclScrollVar w] cset w "yscrollcommand" (TkCommand (varname sc ++ " set")) execTclScript [tkDeclScrollVar sc] return w scrollbar _ _ w = return w moveto ax w f | isWfOrientation w ax = execMethod w (\nm -> [tkMoveTo ax nm f]) moveto _ _ _ = done scroll ax w num what | isWfOrientation w ax = execMethod w (\nm -> [tkScroll ax nm num what]) scroll ax w num what = done view ax w = evalMethod w (tkView ax) -- ----------------------------------------------------------------------- -- datatype -- ----------------------------------------------------------------------- --- -- The ScrollBar datatype. newtype ScrollBar = ScrollBar GUIOBJECT deriving Eq -- ----------------------------------------------------------------------- -- constructor -- ----------------------------------------------------------------------- --- -- Constructs a new scrollbar 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 scrollbar. -- @return result - A scrollbar widget. newScrollBar :: Container par => par -> [Config ScrollBar] -> IO ScrollBar newScrollBar par cnf = do w <- createGUIObject (toGUIObject par) SCROLLBAR scrollbarMethods configure (ScrollBar w) cnf -- ----------------------------------------------------------------------- -- ScrollBar configuration options -- ----------------------------------------------------------------------- --- -- Internal. instance GUIObject ScrollBar where --- -- Internal. toGUIObject (ScrollBar w) = w --- -- Internal. cname _ = "ScrollBar" --- -- A scrollbar widget can be destroyed. instance Destroyable ScrollBar where --- -- Destroys a scrollbar widget. destroy = destroy . toGUIObject --- -- A scrollbar widget has standard widget properties -- (concerning focus, cursor). instance Widget ScrollBar --- -- A scrollbar widget has a configureable border. instance HasBorder ScrollBar --- -- A scrollbar widget has a background and activebackground -- (regarding slider) colour. instance HasColour ScrollBar where --- -- Internal. legalColourID w "bg" = True legalColourID w "activebackground" = True -- regards slider actually legalColourID w _ = False --- -- A scrollbar widget is a stateful widget, it can be enabled or -- disabled. instance HasEnable ScrollBar --- -- You can specify the width of a scrollbar. instance HasSize ScrollBar where --- -- Dummy. height _ w = return w --- -- Dummy. getHeight w = return cdefault --- -- The scrollbar has a configureable slider component. instance HasSlider ScrollBar --- -- The scrollbars orientation can be Horizontal or -- Vertical. instance HasOrientation ScrollBar --- -- A scrollbar can have a tooltip. instance HasTooltip ScrollBar -- ----------------------------------------------------------------------- -- ScrollBar commands -- ----------------------------------------------------------------------- --- -- Sets the active element (which can be arrow1, arrow2 or slider). -- @param sc - the concerned scrollbar. -- @param elem - the element to activate. -- @return result - None. activateScrollBarElem :: ScrollBar -> ScrollBarElem -> IO () activateScrollBarElem sc elem = execMethod sc (\nm -> [tkActivate nm elem]) --- -- Gets the active element (arrow1, arrow2 or slider). -- @param sc - the concerned scrollbar. -- @return result - Just [elem] if an element is active, -- otherwise Nothing. getActivatedElem :: ScrollBar -> IO (Maybe ScrollBarElem) getActivatedElem sc = do e <- evalMethod sc (\nm -> [tkGetActivate nm]) case dropWhile isSpace e of "" -> return Nothing x -> return (Just (read x)) --- -- Returns a fraction between 0 and 1 indicating the relative location -- of the given position in the through. -- @param sc - the concerned scrollbar. -- @param pos - the conderned position. -- @return result - The fraction indicating the relative location in the -- through. fraction :: ScrollBar -> Position -> IO Fraction fraction sc pos@(x, y) = evalMethod sc (\nm -> [tkFraction nm x y]) --- -- Returns the ScrollBarElem to indicate what is under -- the given position. -- @param sc - the concerned scrollbar. -- @param pos - the concerned position. -- @return result - Just [elem] if [elem] is -- under the given position, otherwise -- Nothing. identify :: ScrollBar -> Position -> IO (Maybe ScrollBarElem) identify sc pos@(x, y) = do e <- evalMethod sc (\nm -> [tkIdentify nm x y]) case dropWhile (isSpace) e of "" -> return Nothing x -> return (Just (read x)) --- -- Sets the scrollbar parameters. -- @param sc - the concerned scrollbar. -- @param first - fraction between 0 and 1 representing the relative -- position of the top left of the display. -- @param last - fraction between 0 and 1 representing the relative -- position of the bottom right of the display. -- @return result - None. setView :: ScrollBar -> Fraction -> Fraction -> IO () setView sc first last = execMethod sc (\nm -> [tkSet nm first last]) -- ----------------------------------------------------------------------- -- ScrollBar elem -- ----------------------------------------------------------------------- --- -- The ScrollBarElem datatype - representing the elements -- of the scrollbar. data ScrollBarElem = Arrow1 | Trough1 | ScrollBarSlider | Trough2 | Arrow2 deriving (Eq,Ord,Enum) --- -- Internal. instance GUIValue ScrollBarElem where --- -- Internal. cdefault = ScrollBarSlider --- -- Internal. instance Read ScrollBarElem where --- -- Internal. readsPrec p b = case dropWhile (isSpace) b of 'a':'r':'r':'o':'w':'1':xs -> [(Arrow1,xs)] 't':'r':'o':'u':'g':'h':'1':xs -> [(Trough1,xs)] 's':'l':'i':'d':'e':'r':xs -> [(ScrollBarSlider,xs)] 't':'r':'o':'u':'g':'h':'2':xs -> [(Trough2,xs)] 'a':'r':'r':'o':'w':'2':xs -> [(Arrow2,xs)] _ -> [] --- -- Internal. instance Show ScrollBarElem where --- -- Internal. showsPrec d p r = (case p of Arrow1 -> "arrow1" Trough1 -> "trough1" ScrollBarSlider -> "slider" Trough2 -> "trough2" Arrow2 -> "arrow2" ) ++ r -- ----------------------------------------------------------------------- -- scroll unit -- ----------------------------------------------------------------------- --- -- The ScrollUnit datatype - units for scrolling operations. data ScrollUnit = Units | Pages --- -- Internal. instance GUIValue ScrollUnit where --- -- Internal. cdefault = Units --- -- Internal. instance Read ScrollUnit where --- -- Internal. readsPrec p b = case dropWhile (isSpace) b of 'u':'n':'i':'t':'s':xs -> [(Units,xs)] 'p':'a':'g':'e':'s':xs -> [(Pages,xs)] _ -> [] --- -- Internal. instance Show ScrollUnit where --- -- Internal. showsPrec d p r = (case p of Units -> "units" Pages -> "pages" ) ++ r -- ----------------------------------------------------------------------- -- Scrollbar methods -- ----------------------------------------------------------------------- scrollbarMethods = defMethods { cleanupCmd = tkCleanupScrollBar, createCmd = tkCreateScrollBar } -- ----------------------------------------------------------------------- -- Tk commands -- ----------------------------------------------------------------------- tkCreateScrollBar :: ObjectName -> ObjectKind -> ObjectName -> ObjectID -> [ConfigOption] -> TclScript tkCreateScrollBar pnm kind name oid confs = tkDeclVar ("sv" ++ show oid) (show name) ++ (createCmd defMethods) pnm kind name oid confs {-# INLINE tkCreateScrollBar #-} tkCleanupScrollBar :: ObjectID -> ObjectName -> TclScript tkCleanupScrollBar oid _ = tkUndeclVar ("sv" ++ show oid) {-# INLINE tkCleanupScrollBar #-} varname :: GUIObject w => w -> String varname w = (tkDeclScrollVar w) ++ "; $sv" ++ ((show .getObjectNo . toGUIObject) w) {-# INLINE varname #-} tkDeclScrollVar :: GUIObject w => w -> String tkDeclScrollVar w = "global sv" ++ ((show .getObjectNo . toGUIObject) w) {-# INLINE tkDeclScrollVar #-} tkScroll :: Orientation -> ObjectName -> Int -> ScrollUnit -> TclCmd tkScroll ax nm no what = show nm ++ " " ++ oshow ax ++ "view scroll " ++ show no ++ " " ++ show what {-# INLINE tkScroll #-} -- added Oct. '01, still experimental (ludi) tkView :: Orientation -> ObjectName -> TclScript tkView ax nm = [show nm ++ " " ++ oshow ax ++ "view"] {-# INLINE tkView #-} tkMoveTo :: Orientation -> ObjectName -> Fraction -> String tkMoveTo ax nm f = show nm ++ " " ++ oshow ax ++ "view moveto " ++ show f {-# INLINE tkMoveTo #-} tkActivate :: ObjectName -> ScrollBarElem -> String tkActivate nm e = show nm ++ " activate " ++ show e {-# INLINE tkActivate #-} tkGetActivate :: ObjectName -> String tkGetActivate nm = show nm ++ " activate" {-# INLINE tkGetActivate #-} tkFraction :: ObjectName -> Distance -> Distance -> String tkFraction nm x y = show nm ++ " fraction " ++ show x ++ " " ++ show y {-# INLINE tkFraction #-} tkIdentify :: ObjectName -> Distance -> Distance -> String tkIdentify nm x y = show nm ++ " identify " ++ show x ++ " " ++ show y {-# INLINE tkIdentify #-} tkSet :: ObjectName -> Fraction -> Fraction -> String tkSet nm x y = show nm ++ " set " ++ show x ++ " " ++ show y {-# INLINE tkSet #-} oshow Horizontal = "x" oshow Vertical = "y"