summaryrefslogtreecommitdiffstats
path: root/lib/Phi/Widget.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Phi/Widget.hs')
-rw-r--r--lib/Phi/Widget.hs54
1 files changed, 20 insertions, 34 deletions
diff --git a/lib/Phi/Widget.hs b/lib/Phi/Widget.hs
index 68bed1b..791eff1 100644
--- a/lib/Phi/Widget.hs
+++ b/lib/Phi/Widget.hs
@@ -1,10 +1,9 @@
-{-# LANGUAGE ExistentialQuantification, StandaloneDeriving, MultiParamTypeClasses, FunctionalDependencies, TypeSynonymInstances, FlexibleInstances #-}
+{-# LANGUAGE ExistentialQuantification, StandaloneDeriving, DeriveDataTypeable, MultiParamTypeClasses, FunctionalDependencies, TypeSynonymInstances, FlexibleInstances #-}
module Phi.Widget ( Display(..)
, withDisplay
, getAtoms
- , getScreenWindows
- , getScreens
+ , XMessage(..)
, unionArea
, SurfaceSlice(..)
, Widget(..)
@@ -29,6 +28,7 @@ import Control.Monad.State.Strict hiding (lift)
import Control.Monad.IO.Class
import Data.Maybe
+import Data.Typeable
import qualified Graphics.X11.Xlib as Xlib
import Graphics.Rendering.Cairo
@@ -37,23 +37,19 @@ import Phi.Phi
import Phi.X11.Atoms
-data Display = Display !(MVar Xlib.Display) !Atoms ![(Xlib.Rectangle, Xlib.Window)]
+data Display = Display !(MVar Xlib.Display) !Atoms
withDisplay :: MonadIO m => Display -> (Xlib.Display -> m a) -> m a
-withDisplay (Display dispvar _ _) f = do
+withDisplay (Display dispvar _) f = do
disp <- liftIO $ takeMVar dispvar
a <- f disp
liftIO $ putMVar dispvar disp
return a
getAtoms :: Display -> Atoms
-getAtoms (Display _ atoms _) = atoms
+getAtoms (Display _ atoms) = atoms
-getScreenWindows :: Display -> [(Xlib.Rectangle, Xlib.Window)]
-getScreenWindows (Display _ _ screenWindows) = screenWindows
-
-getScreens :: Display -> [Xlib.Rectangle]
-getScreens = map fst . getScreenWindows
+data XMessage = UpdateScreens [(Xlib.Rectangle, Xlib.Window)] deriving (Show, Typeable)
unionArea :: Xlib.Rectangle -> Xlib.Rectangle -> Int
@@ -75,7 +71,7 @@ unionArea a b = fromIntegral $ uw*uh
data SurfaceSlice = SurfaceSlice !Int !Surface
class Eq s => Widget w s c | w -> s, w -> c where
- initWidget :: w -> Phi -> Display -> IO s
+ initWidget :: w -> Phi -> Display -> [(Xlib.Rectangle, Xlib.Window)] -> IO s
initCache :: w -> c
@@ -84,9 +80,6 @@ class Eq s => Widget w s c | w -> s, w -> c where
weight :: w -> Float
weight _ = 0
- layout :: w -> s -> Int -> Int -> Xlib.Rectangle -> s
- layout _ priv _ _ _ = priv
-
render :: w -> s -> Int -> Int -> Int -> Int -> Xlib.Rectangle -> StateT c IO [(Bool, SurfaceSlice)]
handleMessage :: w -> s -> Message -> s
@@ -125,43 +118,36 @@ renderCached widget state x y w h screen = do
data CompoundWidget a sa ca b sb cb = (Widget a sa ca, Widget b sb cb) => CompoundWidget !a !b
-data CompoundState a sa ca b sb cb = (Widget a sa ca, Widget b sb cb) => CompoundState !sa !sb !Int
+data CompoundState a sa ca b sb cb = (Widget a sa ca, Widget b sb cb) => CompoundState !sa !sb
deriving instance Eq (CompoundState a sa ca b sb cb)
data CompoundCache a sa ca b sb cb = (Widget a sa ca, Widget b sb cb) => CompoundCache !ca !cb
instance Widget (CompoundWidget a sa ca b sb cb) (CompoundState a sa ca b sb cb) (CompoundCache a sa ca b sb cb) where
- initWidget (CompoundWidget a b) phi disp = liftM3 CompoundState (initWidget a phi disp) (initWidget b phi disp) (return 0)
+ initWidget (CompoundWidget a b) phi disp screens = liftM2 CompoundState (initWidget a phi disp screens) (initWidget b phi disp screens)
initCache (CompoundWidget a b) = CompoundCache (initCache a) (initCache b)
- minSize (CompoundWidget a b) (CompoundState da db _) height screen = minSize a da height screen + minSize b db height screen
+ minSize (CompoundWidget a b) (CompoundState da db) height screen = minSize a da height screen + minSize b db height screen
weight (CompoundWidget a b) = weight' a + weight' b
- layout c@(CompoundWidget a b) s@(CompoundState sa sb _) width height screen = CompoundState sa' sb' xb
- where
- sizesum = minSize c s height screen
- wsum = let wsum = weight c
- in if wsum > 0 then wsum else 1
+ render c@(CompoundWidget a b) s@(CompoundState sa sb) x y w h screen = do
+ let sizesum = minSize c s h screen
+ wsum = let wsum = weight c
+ in if wsum > 0 then wsum else 1
+ surplus = w - sizesum
+ xb = floor $ (fromIntegral $ minSize a sa h screen) + (fromIntegral surplus)*(weight' a)/wsum
- surplus = width - sizesum
-
- (xb, sa') = layoutWidget a sa
- (_, sb') = layoutWidget b sb
-
- layoutWidget w s = let wWidth = floor $ (fromIntegral $ minSize w s height screen) + (fromIntegral surplus)*(weight' w)/wsum
- in (wWidth, layout w s wWidth height screen)
-
- render (CompoundWidget a b) (CompoundState sa sb xb) x y w h screen = do
CompoundCache ca cb <- get
+
(surfacea, ca') <- liftIO $ flip runStateT ca $ render a sa x y xb h screen
(surfaceb, cb') <- liftIO $ flip runStateT cb $ render b sb (x+xb) y (w-xb) h screen
put $ CompoundCache ca' cb'
return $ surfacea ++ map (\(updated, SurfaceSlice x surface) -> (updated, SurfaceSlice (x+xb) surface)) surfaceb
- handleMessage (CompoundWidget a b) (CompoundState sa sb xb) message = CompoundState (handleMessage a sa message) (handleMessage b sb message) xb
+ handleMessage (CompoundWidget a b) (CompoundState sa sb) message = CompoundState (handleMessage a sa message) (handleMessage b sb message)
weight' :: (Widget a sa ca) => a -> Float
weight' = max 0 . weight
@@ -172,7 +158,7 @@ a <~> b = CompoundWidget a b
data Separator = Separator !Int !Float deriving (Show, Eq)
instance Widget Separator () (RenderCache Separator ()) where
- initWidget _ _ _ = return ()
+ initWidget _ _ _ _ = return ()
initCache _ = createRenderCache $ \_ _ _ _ _ _ _ -> do
setOperator OperatorClear
paint