add serializable SwitchTrans (a.k.a. MultiToggle)

This commit is contained in:
Lukas Mai 2007-11-06 00:58:19 +00:00
parent 8d5afd87d7
commit edb3d350be
3 changed files with 151 additions and 0 deletions

View File

@ -57,6 +57,7 @@ import XMonad.Maximize ()
-- import XMonad.Mosaic () -- import XMonad.Mosaic ()
import XMonad.MosaicAlt () import XMonad.MosaicAlt ()
import XMonad.MouseGestures () import XMonad.MouseGestures ()
import XMonad.MultiToggle ()
import XMonad.NamedWindows () import XMonad.NamedWindows ()
import XMonad.NoBorders () import XMonad.NoBorders ()
import XMonad.ResizableTile () import XMonad.ResizableTile ()

View File

@ -0,0 +1,149 @@
{-# OPTIONS_GHC -fglasgow-exts #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Layout.MultiToggle
-- Copyright : (c) Lukas Mai
-- License : BSD-style (see LICENSE)
--
-- Maintainer : <l.mai@web.de>
-- Stability : unstable
-- Portability : unportable
module XMonad.Layout.MultiToggle (
EL(..),
unEL,
LayoutTransformer(..),
Toggle(..),
(.*.),
HNil(..),
mkToggle
) where
import XMonad
import Control.Arrow
import Data.Typeable
import Data.Maybe
data EL a = forall l. (LayoutClass l a) => EL (l a)
unEL :: EL a -> (forall l. (LayoutClass l a) => l a -> b) -> b
unEL (EL x) k = k x
class (Eq t, Typeable t) => LayoutTransformer t a | t -> a where
transform :: t -> EL a -> EL a
data Toggle a = forall t. (LayoutTransformer t a) => Toggle t
deriving (Typeable)
instance (Typeable a) => Message (Toggle a)
data MultiToggleS ts l a = MultiToggleS (l a) (Maybe Int) ts
deriving (Read, Show)
data MultiToggle ts l a = MultiToggle{
baseLayout :: l a,
currLayout :: EL a,
currIndex :: Maybe Int,
currTrans :: EL a -> EL a,
transformers :: ts
}
expand :: (LayoutClass l a, HList ts a) => MultiToggleS ts l a -> MultiToggle ts l a
expand (MultiToggleS b i ts) =
resolve ts (fromMaybe (-1) i) id
(\x mt ->
let g = transform x in
mt{
currLayout = g . EL $ baseLayout mt,
currTrans = g
}
)
(MultiToggle b (EL b) i id ts)
collapse :: MultiToggle ts l a -> MultiToggleS ts l a
collapse mt = MultiToggleS (baseLayout mt) (currIndex mt) (transformers mt)
instance (LayoutClass l a, Read (l a), HList ts a, Read ts) => Read (MultiToggle ts l a) where
readsPrec p s = map (first expand) $ readsPrec p s
instance (Show ts, Show (l a)) => Show (MultiToggle ts l a) where
showsPrec p = showsPrec p . collapse
mkToggle :: (LayoutClass l a) => ts -> l a -> MultiToggle ts l a
mkToggle ts l = MultiToggle l (EL l) Nothing id ts
data HNil = HNil deriving (Read, Show)
data HCons a b = HCons a b deriving (Read, Show)
infixr 0 .*.
(.*.) :: (HList b w) => a -> b -> HCons a b
(.*.) = HCons
class HList c a where
find :: (LayoutTransformer t a) => c -> t -> Maybe Int
resolve :: c -> Int -> b -> (forall t. (LayoutTransformer t a) => t -> b) -> b
instance HList HNil w where
find HNil _ = Nothing
resolve HNil _ d _ = d
instance (LayoutTransformer a w, HList b w) => HList (HCons a b) w where
find (HCons x xs) t
| t `geq` x = Just 0
| otherwise = fmap succ (find xs t)
resolve (HCons x xs) n d k =
case n `compare` 0 of
LT -> d
EQ -> k x
GT -> resolve xs (pred n) d k
geq :: (Typeable a, Eq a, Typeable b) => a -> b -> Bool
geq a b = Just a == cast b
acceptChange :: (LayoutClass l' a) => MultiToggle ts l a -> ((l' a -> MultiToggle ts l a) -> b -> c) -> X b -> X c
acceptChange mt f = fmap (f (\x -> mt{ currLayout = EL x }))
instance (Typeable a, Show ts, HList ts a, LayoutClass l a) => LayoutClass (MultiToggle ts l) a where
description _ = "MultiToggle"
pureLayout mt r s = currLayout mt `unEL` \l -> pureLayout l r s
doLayout mt r s = currLayout mt `unEL` \l -> acceptChange mt (fmap . fmap) (doLayout l r s)
handleMessage mt m
| Just (Toggle t) <- fromMessage m
, i@(Just _) <- find (transformers mt) t
= currLayout mt `unEL` \l ->
if i == currIndex mt
then do
handleMessage l (SomeMessage ReleaseResources)
return . Just $
mt{
currLayout = EL $ baseLayout mt,
currIndex = Nothing,
currTrans = id
}
else do
handleMessage l (SomeMessage ReleaseResources)
let f = transform t
return . Just $
mt{
currLayout = f . EL $ baseLayout mt,
currIndex = i,
currTrans = f
}
| fromMessage m == Just ReleaseResources ||
fromMessage m == Just Hide
= currLayout mt `unEL` \l -> acceptChange mt fmap (handleMessage l m)
| otherwise = do
ml <- handleMessage (baseLayout mt) m
case ml of
Nothing -> return Nothing
Just b' -> currLayout mt `unEL` \l -> do
handleMessage l (SomeMessage ReleaseResources)
return . Just $
mt{ baseLayout = b', currLayout = currTrans mt . EL $ b' }

View File

@ -73,6 +73,7 @@ library
XMonad.Layout.Maximize XMonad.Layout.Maximize
XMonad.Layout.MosaicAlt XMonad.Layout.MosaicAlt
-- XMonad.Layout.Mosaic -- XMonad.Layout.Mosaic
XMonad.Layout.MultiToggle
XMonad.Layout.NoBorders XMonad.Layout.NoBorders
XMonad.Layout.ResizableTile XMonad.Layout.ResizableTile
XMonad.Layout.Roledex XMonad.Layout.Roledex