{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
module XMonad.Layout.ThreeColumns (
ThreeCol(..)
) where
import XMonad
import XMonad.Prelude
import qualified XMonad.StackSet as W
import Data.Ratio
data ThreeCol a = ThreeColMid { ThreeCol a -> Int
threeColNMaster :: !Int, ThreeCol a -> Rational
threeColDelta :: !Rational, ThreeCol a -> Rational
threeColFrac :: !Rational}
| ThreeCol { threeColNMaster :: !Int, threeColDelta :: !Rational, threeColFrac :: !Rational}
deriving (Int -> ThreeCol a -> ShowS
[ThreeCol a] -> ShowS
ThreeCol a -> String
(Int -> ThreeCol a -> ShowS)
-> (ThreeCol a -> String)
-> ([ThreeCol a] -> ShowS)
-> Show (ThreeCol a)
forall a. Int -> ThreeCol a -> ShowS
forall a. [ThreeCol a] -> ShowS
forall a. ThreeCol a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ThreeCol a] -> ShowS
$cshowList :: forall a. [ThreeCol a] -> ShowS
show :: ThreeCol a -> String
$cshow :: forall a. ThreeCol a -> String
showsPrec :: Int -> ThreeCol a -> ShowS
$cshowsPrec :: forall a. Int -> ThreeCol a -> ShowS
Show,ReadPrec [ThreeCol a]
ReadPrec (ThreeCol a)
Int -> ReadS (ThreeCol a)
ReadS [ThreeCol a]
(Int -> ReadS (ThreeCol a))
-> ReadS [ThreeCol a]
-> ReadPrec (ThreeCol a)
-> ReadPrec [ThreeCol a]
-> Read (ThreeCol a)
forall a. ReadPrec [ThreeCol a]
forall a. ReadPrec (ThreeCol a)
forall a. Int -> ReadS (ThreeCol a)
forall a. ReadS [ThreeCol a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ThreeCol a]
$creadListPrec :: forall a. ReadPrec [ThreeCol a]
readPrec :: ReadPrec (ThreeCol a)
$creadPrec :: forall a. ReadPrec (ThreeCol a)
readList :: ReadS [ThreeCol a]
$creadList :: forall a. ReadS [ThreeCol a]
readsPrec :: Int -> ReadS (ThreeCol a)
$creadsPrec :: forall a. Int -> ReadS (ThreeCol a)
Read)
instance LayoutClass ThreeCol a where
pureLayout :: ThreeCol a -> Rectangle -> Stack a -> [(a, Rectangle)]
pureLayout (ThreeCol Int
n Rational
_ Rational
f) Rectangle
r = Bool -> Int -> Rational -> Rectangle -> Stack a -> [(a, Rectangle)]
forall a.
Bool -> Int -> Rational -> Rectangle -> Stack a -> [(a, Rectangle)]
doL Bool
False Int
n Rational
f Rectangle
r
pureLayout (ThreeColMid Int
n Rational
_ Rational
f) Rectangle
r = Bool -> Int -> Rational -> Rectangle -> Stack a -> [(a, Rectangle)]
forall a.
Bool -> Int -> Rational -> Rectangle -> Stack a -> [(a, Rectangle)]
doL Bool
True Int
n Rational
f Rectangle
r
handleMessage :: ThreeCol a -> SomeMessage -> X (Maybe (ThreeCol a))
handleMessage ThreeCol a
l SomeMessage
m =
Maybe (ThreeCol a) -> X (Maybe (ThreeCol a))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (ThreeCol a) -> X (Maybe (ThreeCol a)))
-> Maybe (ThreeCol a) -> X (Maybe (ThreeCol a))
forall a b. (a -> b) -> a -> b
$ [Maybe (ThreeCol a)] -> Maybe (ThreeCol a)
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum [(Resize -> ThreeCol a) -> Maybe Resize -> Maybe (ThreeCol a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Resize -> ThreeCol a
forall a. Resize -> ThreeCol a
resize (SomeMessage -> Maybe Resize
forall m. Message m => SomeMessage -> Maybe m
fromMessage SomeMessage
m)
,(IncMasterN -> ThreeCol a)
-> Maybe IncMasterN -> Maybe (ThreeCol a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IncMasterN -> ThreeCol a
forall a. IncMasterN -> ThreeCol a
incmastern (SomeMessage -> Maybe IncMasterN
forall m. Message m => SomeMessage -> Maybe m
fromMessage SomeMessage
m)]
where resize :: Resize -> ThreeCol a
resize Resize
Shrink = ThreeCol a
l { threeColFrac :: Rational
threeColFrac = Rational -> Rational -> Rational
forall a. Ord a => a -> a -> a
max (-Rational
0.5) (Rational -> Rational) -> Rational -> Rational
forall a b. (a -> b) -> a -> b
$ Rational
fRational -> Rational -> Rational
forall a. Num a => a -> a -> a
-Rational
d }
resize Resize
Expand = ThreeCol a
l { threeColFrac :: Rational
threeColFrac = Rational -> Rational -> Rational
forall a. Ord a => a -> a -> a
min Rational
1 (Rational -> Rational) -> Rational -> Rational
forall a b. (a -> b) -> a -> b
$ Rational
fRational -> Rational -> Rational
forall a. Num a => a -> a -> a
+Rational
d }
incmastern :: IncMasterN -> ThreeCol a
incmastern (IncMasterN Int
x) = ThreeCol a
l { threeColNMaster :: Int
threeColNMaster = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
x) }
n :: Int
n = ThreeCol a -> Int
forall a. ThreeCol a -> Int
threeColNMaster ThreeCol a
l
d :: Rational
d = ThreeCol a -> Rational
forall a. ThreeCol a -> Rational
threeColDelta ThreeCol a
l
f :: Rational
f = ThreeCol a -> Rational
forall a. ThreeCol a -> Rational
threeColFrac ThreeCol a
l
description :: ThreeCol a -> String
description ThreeCol a
_ = String
"ThreeCol"
doL :: Bool-> Int-> Rational-> Rectangle-> W.Stack a-> [(a, Rectangle)]
doL :: Bool -> Int -> Rational -> Rectangle -> Stack a -> [(a, Rectangle)]
doL Bool
m Int
n Rational
f Rectangle
r = ([a] -> [Rectangle] -> [(a, Rectangle)])
-> ([a] -> [Rectangle]) -> [a] -> [(a, Rectangle)]
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap [a] -> [Rectangle] -> [(a, Rectangle)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Bool -> Rational -> Rectangle -> Int -> Int -> [Rectangle]
tile3 Bool
m Rational
f Rectangle
r Int
n (Int -> [Rectangle]) -> ([a] -> Int) -> [a] -> [Rectangle]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length) ([a] -> [(a, Rectangle)])
-> (Stack a -> [a]) -> Stack a -> [(a, Rectangle)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stack a -> [a]
forall a. Stack a -> [a]
W.integrate
tile3 :: Bool -> Rational -> Rectangle -> Int -> Int -> [Rectangle]
tile3 :: Bool -> Rational -> Rectangle -> Int -> Int -> [Rectangle]
tile3 Bool
middle Rational
f Rectangle
r Int
nmaster Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
nmaster Bool -> Bool -> Bool
|| Int
nmaster Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Int -> Rectangle -> [Rectangle]
splitVertically Int
n Rectangle
r
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
nmasterInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1 = Int -> Rectangle -> [Rectangle]
splitVertically Int
nmaster Rectangle
s1 [Rectangle] -> [Rectangle] -> [Rectangle]
forall a. [a] -> [a] -> [a]
++ Int -> Rectangle -> [Rectangle]
splitVertically (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
nmaster) Rectangle
s2
| Bool
otherwise = Int -> Rectangle -> [Rectangle]
splitVertically Int
nmaster Rectangle
r1 [Rectangle] -> [Rectangle] -> [Rectangle]
forall a. [a] -> [a] -> [a]
++ Int -> Rectangle -> [Rectangle]
splitVertically Int
nslave1 Rectangle
r2 [Rectangle] -> [Rectangle] -> [Rectangle]
forall a. [a] -> [a] -> [a]
++ Int -> Rectangle -> [Rectangle]
splitVertically Int
nslave2 Rectangle
r3
where (Rectangle
r1, Rectangle
r2, Rectangle
r3) = Bool -> Rational -> Rectangle -> (Rectangle, Rectangle, Rectangle)
split3HorizontallyBy Bool
middle (if Rational
fRational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
<Rational
0 then Rational
1Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+Rational
2Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
*Rational
f else Rational
f) Rectangle
r
(Rectangle
s1, Rectangle
s2) = Rational -> Rectangle -> (Rectangle, Rectangle)
forall r. RealFrac r => r -> Rectangle -> (Rectangle, Rectangle)
splitHorizontallyBy (if Rational
fRational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
<Rational
0 then Rational
1Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+Rational
f else Rational
f) Rectangle
r
nslave :: Int
nslave = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
nmaster
nslave1 :: Int
nslave1 = Ratio Int -> Int
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Int
nslave Int -> Int -> Ratio Int
forall a. Integral a => a -> a -> Ratio a
% Int
2)
nslave2 :: Int
nslave2 = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
nmaster Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
nslave1
split3HorizontallyBy :: Bool -> Rational -> Rectangle -> (Rectangle, Rectangle, Rectangle)
split3HorizontallyBy :: Bool -> Rational -> Rectangle -> (Rectangle, Rectangle, Rectangle)
split3HorizontallyBy Bool
middle Rational
f (Rectangle Position
sx Position
sy Dimension
sw Dimension
sh) =
if Bool
middle
then ( Position -> Position -> Dimension -> Dimension -> Rectangle
Rectangle (Position
sx Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Dimension
r3w) Position
sy Dimension
r1w Dimension
sh
, Position -> Position -> Dimension -> Dimension -> Rectangle
Rectangle Position
sx Position
sy Dimension
r3w Dimension
sh
, Position -> Position -> Dimension -> Dimension -> Rectangle
Rectangle (Position
sx Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Dimension
r3w Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Dimension
r1w) Position
sy Dimension
r2w Dimension
sh )
else ( Position -> Position -> Dimension -> Dimension -> Rectangle
Rectangle Position
sx Position
sy Dimension
r1w Dimension
sh
, Position -> Position -> Dimension -> Dimension -> Rectangle
Rectangle (Position
sx Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Dimension
r1w) Position
sy Dimension
r2w Dimension
sh
, Position -> Position -> Dimension -> Dimension -> Rectangle
Rectangle (Position
sx Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Dimension
r1w Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fromIntegral Dimension
r2w) Position
sy Dimension
r3w Dimension
sh )
where r1w :: Dimension
r1w = Rational -> Dimension
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Rational -> Dimension) -> Rational -> Dimension
forall a b. (a -> b) -> a -> b
$ Dimension -> Rational
forall a b. (Integral a, Num b) => a -> b
fromIntegral Dimension
sw Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
f
r2w :: Dimension
r2w = Ratio Dimension -> Dimension
forall a b. (RealFrac a, Integral b) => a -> b
ceiling ( (Dimension
sw Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Dimension
r1w) Dimension -> Dimension -> Ratio Dimension
forall a. Integral a => a -> a -> Ratio a
% Dimension
2 )
r3w :: Dimension
r3w = Dimension
sw Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Dimension
r1w Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Dimension
r2w