-- | A simple scroll pane for a scrolled widget. module HTk.Toolkit.ScrollBox ( ScrollBox(..), newScrollBox, getScrolledWidget, getScrollBars ) where import Util.Computation import Events.Synchronized import HTk.Toplevel.HTk import HTk.Kernel.Core -- ----------------------------------------------------------------------- -- type -- ----------------------------------------------------------------------- -- | The @ScrollBox@ datatype. data ScrollBox a = ScrollBox { fScrollFrame :: Frame, fPadFrames :: [Frame], fScrollBars :: [ScrollBar], fScrolledWidget :: a } -- ----------------------------------------------------------------------- -- constructor -- ----------------------------------------------------------------------- -- | Constructs a new scrollbox and returns a handler. newScrollBox :: (Widget wid, HasScroller wid, Container par) => par -- ^ the parent widget, which has to be a container widget. -> (Frame -> IO wid) -- ^ a function that returns the scrollbox\'es content for -- a given parent container. -> [Config (ScrollBox wid)] -- ^ the list of configuration options for this scrollbox. -> IO (ScrollBox wid, wid) -- ^ A scrollbox. newScrollBox par wfun cnf = do f <- newFrame par [] w <- wfun f let sz = cm 0.3 sz' = if scrollY then sz else 0 -- width of y scrollbar scrollY = (isWfOrientation w Vertical) scrollX = (isWfOrientation w Horizontal) fl <- newFrame f [width sz'] pack fl [Fill Y, Side AtRight] (sf,sby) <- if scrollY then do sb <- newScrollBar fl [width sz, orient Vertical] pack sb [Expand On, Fill Y, Side AtTop] configure w [scrollbar Vertical sb] sf <- newFrame fl [width sz, height (cm 0.5)] pack sf [Side AtBottom] return ([sf],[sb]) else return ([],[]) sbx <- if scrollX then do sb <- newScrollBar f [width sz, orient Horizontal] pack sb [Side AtBottom, Fill X] configure w [scrollbar Horizontal sb] return [sb] else return [] let sbox = (ScrollBox f (fl:sf) (sbx ++ sby) w) configure sbox cnf pack w [Fill Both, Expand On] return (sbox, w) -- ----------------------------------------------------------------------- -- instances -- ----------------------------------------------------------------------- -- | Internal. instance Eq (ScrollBox a) where w1 == w2 = (toGUIObject w1) == (toGUIObject w2) -- | Internal. instance GUIObject (ScrollBox a) where toGUIObject (ScrollBox w _ _ _) = toGUIObject w cname _ = "ScrollBox" -- | A scrollbox can be destroyed. instance Destroyable (ScrollBox a) where -- Destroys a scrollbox. destroy = destroy . toGUIObject -- | A scrollbox has standard widget properties -- (concerning focus, cursor). instance (Widget a, HasScroller a) => Widget (ScrollBox a) where cursor c sb = do foreach (fPadFrames sb) (cursor c) cursor c (fScrollFrame sb) foreach (fScrollBars sb) (cursor c) cursor c (fScrolledWidget sb) return sb -- | A scrollbox has a configureable foreground and background colour. instance (HasColour a,HasScroller a) => HasColour (ScrollBox a) where legalColourID _ _ = True setColour sb cid c = do foreach (fPadFrames sb) (\f -> setColour f cid c) setColour (fScrollFrame sb) cid c foreach (fScrollBars sb) (\s -> setColour s cid c) return sb -- | A scrollbox has a configureable border. instance HasBorder (ScrollBox a) -- | A scrollbox has scrollbars. instance HasScroller a => HasScroller (ScrollBox a) where isWfOrientation (ScrollBox _ _ _ sw) axis = isWfOrientation sw axis -- Dummy. scrollbar _ _ sb = return sb -- already done -- Moves the given axis to the given fraction. moveto axis (ScrollBox _ _ _ sw) fraction = moveto axis sw fraction -- Scrolls the given axis by the given amount. scroll axis (ScrollBox _ _ _ sw) step unit = scroll axis sw step unit -- | You can synchronize on a scrollbox. instance Synchronized (ScrollBox a) where -- Synchronizes on a scrollbox. synchronize = synchronize . toGUIObject -- | A scrollbox has a configureable size. instance HasSize (ScrollBox a) where -- Sets the width of the scrollbox. width w scb = fScrollFrame scb # width w >> return scb -- Sets the height of the scrollbox. height h scb = fScrollFrame scb # height h >> return scb -- ----------------------------------------------------------------------- -- selectors -- ----------------------------------------------------------------------- -- | Gets the scrolled widget from a scrollbox. getScrolledWidget :: (Widget a, HasScroller a) => ScrollBox a -> a getScrolledWidget = fScrolledWidget -- | Gets the scrollbars from a scrollbox. getScrollBars :: HasScroller a => ScrollBox a -> [ScrollBar] getScrollBars = fScrollBars