{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, PatternGuards #-}
module XMonad.Layout.Gaps (
Direction2D(..), Gaps,
GapSpec, gaps, gaps', GapMessage(..),
weakModifyGaps, modifyGap, setGaps, setGap
) where
import XMonad.Prelude (delete, fi)
import XMonad.Core
import Graphics.X11 (Rectangle(..))
import XMonad.Layout.LayoutModifier
import XMonad.Util.Types (Direction2D(..))
type GapSpec = [(Direction2D,Int)]
data Gaps a = Gaps GapSpec [Direction2D]
deriving (Int -> Gaps a -> ShowS
forall a. Int -> Gaps a -> ShowS
forall a. [Gaps a] -> ShowS
forall a. Gaps a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Gaps a] -> ShowS
$cshowList :: forall a. [Gaps a] -> ShowS
show :: Gaps a -> String
$cshow :: forall a. Gaps a -> String
showsPrec :: Int -> Gaps a -> ShowS
$cshowsPrec :: forall a. Int -> Gaps a -> ShowS
Show, ReadPrec [Gaps a]
ReadPrec (Gaps a)
ReadS [Gaps a]
forall a. ReadPrec [Gaps a]
forall a. ReadPrec (Gaps a)
forall a. Int -> ReadS (Gaps a)
forall a. ReadS [Gaps a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Gaps a]
$creadListPrec :: forall a. ReadPrec [Gaps a]
readPrec :: ReadPrec (Gaps a)
$creadPrec :: forall a. ReadPrec (Gaps a)
readList :: ReadS [Gaps a]
$creadList :: forall a. ReadS [Gaps a]
readsPrec :: Int -> ReadS (Gaps a)
$creadsPrec :: forall a. Int -> ReadS (Gaps a)
Read)
data GapMessage = ToggleGaps
| ToggleGap !Direction2D
| IncGap !Int !Direction2D
| DecGap !Int !Direction2D
| ModifyGaps (GapSpec -> GapSpec)
instance Message GapMessage
instance LayoutModifier Gaps a where
modifyLayout :: forall (l :: * -> *).
LayoutClass l a =>
Gaps a
-> Workspace String (l a) a
-> Rectangle
-> X ([(a, Rectangle)], Maybe (l a))
modifyLayout Gaps a
g Workspace String (l a) a
w Rectangle
r = forall (layout :: * -> *) a.
LayoutClass layout a =>
Workspace String (layout a) a
-> Rectangle -> X ([(a, Rectangle)], Maybe (layout a))
runLayout Workspace String (l a) a
w (forall a. Gaps a -> Rectangle -> Rectangle
applyGaps Gaps a
g Rectangle
r)
pureMess :: Gaps a -> SomeMessage -> Maybe (Gaps a)
pureMess (Gaps GapSpec
conf [Direction2D]
cur) SomeMessage
m
| Just GapMessage
ToggleGaps <- forall m. Message m => SomeMessage -> Maybe m
fromMessage SomeMessage
m
= forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. GapSpec -> [Direction2D] -> Gaps a
Gaps GapSpec
conf (GapSpec -> [Direction2D] -> [Direction2D]
toggleGaps GapSpec
conf [Direction2D]
cur)
| Just (ToggleGap Direction2D
d) <- forall m. Message m => SomeMessage -> Maybe m
fromMessage SomeMessage
m
= forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. GapSpec -> [Direction2D] -> Gaps a
Gaps GapSpec
conf (GapSpec -> [Direction2D] -> Direction2D -> [Direction2D]
toggleGap GapSpec
conf [Direction2D]
cur Direction2D
d)
| Just (IncGap Int
i Direction2D
d) <- forall m. Message m => SomeMessage -> Maybe m
fromMessage SomeMessage
m
= forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. GapSpec -> [Direction2D] -> Gaps a
Gaps (GapSpec -> GapSpec
limit forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int) -> Direction2D -> GapSpec -> GapSpec
continuation (forall a. Num a => a -> a -> a
+ Int
i ) Direction2D
d forall a b. (a -> b) -> a -> b
$ GapSpec
conf) [Direction2D]
cur
| Just (DecGap Int
i Direction2D
d) <- forall m. Message m => SomeMessage -> Maybe m
fromMessage SomeMessage
m
= forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. GapSpec -> [Direction2D] -> Gaps a
Gaps (GapSpec -> GapSpec
limit forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int) -> Direction2D -> GapSpec -> GapSpec
continuation (forall a. Num a => a -> a -> a
+(-Int
i)) Direction2D
d forall a b. (a -> b) -> a -> b
$ GapSpec
conf) [Direction2D]
cur
| Just (ModifyGaps GapSpec -> GapSpec
f) <- forall m. Message m => SomeMessage -> Maybe m
fromMessage SomeMessage
m
= forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. GapSpec -> [Direction2D] -> Gaps a
Gaps (GapSpec -> GapSpec
limit forall b c a. (b -> c) -> (a -> b) -> a -> c
. GapSpec -> GapSpec
f forall a b. (a -> b) -> a -> b
$ GapSpec
conf) [Direction2D]
cur
| Bool
otherwise = forall a. Maybe a
Nothing
weakModifyGaps :: (Direction2D -> Int -> Int) -> GapMessage
weakModifyGaps :: (Direction2D -> Int -> Int) -> GapMessage
weakModifyGaps = (GapSpec -> GapSpec) -> GapMessage
ModifyGaps forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Direction2D -> Int -> Int) -> GapSpec -> GapSpec
weakToStrong
modifyGap :: (Int -> Int) -> Direction2D -> GapMessage
modifyGap :: (Int -> Int) -> Direction2D -> GapMessage
modifyGap Int -> Int
f Direction2D
d = (GapSpec -> GapSpec) -> GapMessage
ModifyGaps forall a b. (a -> b) -> a -> b
$ (Int -> Int) -> Direction2D -> GapSpec -> GapSpec
continuation Int -> Int
f Direction2D
d
setGaps :: GapSpec -> GapMessage
setGaps :: GapSpec -> GapMessage
setGaps = (GapSpec -> GapSpec) -> GapMessage
ModifyGaps forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const
setGap :: Int -> Direction2D -> GapMessage
setGap :: Int -> Direction2D -> GapMessage
setGap = (Int -> Int) -> Direction2D -> GapMessage
modifyGap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const
limit :: GapSpec -> GapSpec
limit :: GapSpec -> GapSpec
limit = (Direction2D -> Int -> Int) -> GapSpec -> GapSpec
weakToStrong forall a b. (a -> b) -> a -> b
$ \Direction2D
_ -> forall a. Ord a => a -> a -> a
max Int
0
weakToStrong :: (Direction2D -> Int -> Int) -> GapSpec -> GapSpec
weakToStrong :: (Direction2D -> Int -> Int) -> GapSpec -> GapSpec
weakToStrong Direction2D -> Int -> Int
f GapSpec
gs = forall a b. [a] -> [b] -> [(a, b)]
zip (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst GapSpec
gs) (forall a b. (a -> b) -> [a] -> [b]
map (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Direction2D -> Int -> Int
f) GapSpec
gs)
continuation :: (Int -> Int) -> Direction2D -> GapSpec -> GapSpec
continuation :: (Int -> Int) -> Direction2D -> GapSpec -> GapSpec
continuation Int -> Int
f Direction2D
d1 = (Direction2D -> Int -> Int) -> GapSpec -> GapSpec
weakToStrong Direction2D -> Int -> Int
h
where h :: Direction2D -> Int -> Int
h Direction2D
d2 | Direction2D
d2 forall a. Eq a => a -> a -> Bool
== Direction2D
d1 = Int -> Int
f
| Bool
otherwise = forall a. a -> a
id
applyGaps :: Gaps a -> Rectangle -> Rectangle
applyGaps :: forall a. Gaps a -> Rectangle -> Rectangle
applyGaps Gaps a
gs Rectangle
r = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall {a}.
Integral a =>
(Direction2D, a) -> Rectangle -> Rectangle
applyGap Rectangle
r (forall a. Gaps a -> GapSpec
activeGaps Gaps a
gs)
where
applyGap :: (Direction2D, a) -> Rectangle -> Rectangle
applyGap (Direction2D
U,a
z) (Rectangle Position
x Position
y Dimension
w Dimension
h) = Position -> Position -> Dimension -> Dimension -> Rectangle
Rectangle Position
x (Position
y forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fi a
z) Dimension
w (Dimension
h forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fi a
z)
applyGap (Direction2D
D,a
z) (Rectangle Position
x Position
y Dimension
w Dimension
h) = Position -> Position -> Dimension -> Dimension -> Rectangle
Rectangle Position
x Position
y Dimension
w (Dimension
h forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fi a
z)
applyGap (Direction2D
L,a
z) (Rectangle Position
x Position
y Dimension
w Dimension
h) = Position -> Position -> Dimension -> Dimension -> Rectangle
Rectangle (Position
x forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fi a
z) Position
y (Dimension
w forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fi a
z) Dimension
h
applyGap (Direction2D
R,a
z) (Rectangle Position
x Position
y Dimension
w Dimension
h) = Position -> Position -> Dimension -> Dimension -> Rectangle
Rectangle Position
x Position
y (Dimension
w forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fi a
z) Dimension
h
activeGaps :: Gaps a -> GapSpec
activeGaps :: forall a. Gaps a -> GapSpec
activeGaps (Gaps GapSpec
conf [Direction2D]
cur) = forall a. (a -> Bool) -> [a] -> [a]
filter ((forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Direction2D]
cur) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) GapSpec
conf
toggleGaps :: GapSpec -> [Direction2D] -> [Direction2D]
toggleGaps :: GapSpec -> [Direction2D] -> [Direction2D]
toggleGaps GapSpec
conf [] = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst GapSpec
conf
toggleGaps GapSpec
_ [Direction2D]
_ = []
toggleGap :: GapSpec -> [Direction2D] -> Direction2D -> [Direction2D]
toggleGap :: GapSpec -> [Direction2D] -> Direction2D -> [Direction2D]
toggleGap GapSpec
conf [Direction2D]
cur Direction2D
d | Direction2D
d forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Direction2D]
cur = forall a. Eq a => a -> [a] -> [a]
delete Direction2D
d [Direction2D]
cur
| Direction2D
d forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst GapSpec
conf = Direction2D
dforall a. a -> [a] -> [a]
:[Direction2D]
cur
| Bool
otherwise = [Direction2D]
cur
gaps :: GapSpec
-> l a
-> ModifiedLayout Gaps l a
gaps :: forall (l :: * -> *) a. GapSpec -> l a -> ModifiedLayout Gaps l a
gaps GapSpec
g = forall (m :: * -> *) (l :: * -> *) a.
m a -> l a -> ModifiedLayout m l a
ModifiedLayout (forall a. GapSpec -> [Direction2D] -> Gaps a
Gaps GapSpec
g (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst GapSpec
g))
gaps' :: [((Direction2D,Int),Bool)]
-> l a
-> ModifiedLayout Gaps l a
gaps' :: forall (l :: * -> *) a.
[((Direction2D, Int), Bool)] -> l a -> ModifiedLayout Gaps l a
gaps' [((Direction2D, Int), Bool)]
g = forall (m :: * -> *) (l :: * -> *) a.
m a -> l a -> ModifiedLayout m l a
ModifiedLayout (forall a. GapSpec -> [Direction2D] -> Gaps a
Gaps (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst [((Direction2D, Int), Bool)]
g) [Direction2D
d | ((Direction2D
d,Int
_),Bool
v) <- [((Direction2D, Int), Bool)]
g, Bool
v])