{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
module XMonad.Layout.MultiColumns (
multiCol,
MultiCol,
) where
import XMonad
import qualified XMonad.StackSet as W
import XMonad.Prelude
multiCol
:: [Int]
-> Int
-> Rational
-> Rational
-> MultiCol a
multiCol :: forall a. [Int] -> Int -> Rational -> Rational -> MultiCol a
multiCol [Int]
n Int
defn Rational
ds Rational
s = [Int] -> Int -> Rational -> Rational -> Int -> MultiCol a
forall a. [Int] -> Int -> Rational -> Rational -> Int -> MultiCol a
MultiCol ((Int -> Int) -> [Int] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0) [Int]
n) (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 Int
defn) Rational
ds Rational
s Int
0
data MultiCol a = MultiCol
{ forall a. MultiCol a -> [Int]
multiColNWin :: ![Int]
, forall a. MultiCol a -> Int
multiColDefWin :: !Int
, forall a. MultiCol a -> Rational
multiColDeltaSize :: !Rational
, forall a. MultiCol a -> Rational
multiColSize :: !Rational
, forall a. MultiCol a -> Int
multiColActive :: !Int
} deriving (Int -> MultiCol a -> ShowS
[MultiCol a] -> ShowS
MultiCol a -> String
(Int -> MultiCol a -> ShowS)
-> (MultiCol a -> String)
-> ([MultiCol a] -> ShowS)
-> Show (MultiCol a)
forall a. Int -> MultiCol a -> ShowS
forall a. [MultiCol a] -> ShowS
forall a. MultiCol a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Int -> MultiCol a -> ShowS
showsPrec :: Int -> MultiCol a -> ShowS
$cshow :: forall a. MultiCol a -> String
show :: MultiCol a -> String
$cshowList :: forall a. [MultiCol a] -> ShowS
showList :: [MultiCol a] -> ShowS
Show,ReadPrec [MultiCol a]
ReadPrec (MultiCol a)
Int -> ReadS (MultiCol a)
ReadS [MultiCol a]
(Int -> ReadS (MultiCol a))
-> ReadS [MultiCol a]
-> ReadPrec (MultiCol a)
-> ReadPrec [MultiCol a]
-> Read (MultiCol a)
forall a. ReadPrec [MultiCol a]
forall a. ReadPrec (MultiCol a)
forall a. Int -> ReadS (MultiCol a)
forall a. ReadS [MultiCol a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall a. Int -> ReadS (MultiCol a)
readsPrec :: Int -> ReadS (MultiCol a)
$creadList :: forall a. ReadS [MultiCol a]
readList :: ReadS [MultiCol a]
$creadPrec :: forall a. ReadPrec (MultiCol a)
readPrec :: ReadPrec (MultiCol a)
$creadListPrec :: forall a. ReadPrec [MultiCol a]
readListPrec :: ReadPrec [MultiCol a]
Read,MultiCol a -> MultiCol a -> Bool
(MultiCol a -> MultiCol a -> Bool)
-> (MultiCol a -> MultiCol a -> Bool) -> Eq (MultiCol a)
forall a. MultiCol a -> MultiCol a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. MultiCol a -> MultiCol a -> Bool
== :: MultiCol a -> MultiCol a -> Bool
$c/= :: forall a. MultiCol a -> MultiCol a -> Bool
/= :: MultiCol a -> MultiCol a -> Bool
Eq)
instance LayoutClass MultiCol a where
doLayout :: MultiCol a
-> Rectangle -> Stack a -> X ([(a, Rectangle)], Maybe (MultiCol a))
doLayout MultiCol a
l Rectangle
r Stack a
s = ([(a, Rectangle)], Maybe (MultiCol a))
-> X ([(a, Rectangle)], Maybe (MultiCol a))
forall a. a -> X a
forall (m :: * -> *) a. Monad m => a -> m a
return (Stack a -> [Rectangle] -> [(a, Rectangle)]
forall {a} {b}. Stack a -> [b] -> [(a, b)]
combine Stack a
s [Rectangle]
rlist, Maybe (MultiCol a)
forall {a}. Maybe (MultiCol a)
resl)
where rlist :: [Rectangle]
rlist = [Int] -> Rational -> Rectangle -> Int -> [Rectangle]
doL (MultiCol Any -> [Int]
forall a. MultiCol a -> [Int]
multiColNWin MultiCol Any
forall {a}. MultiCol a
l') (MultiCol Any -> Rational
forall a. MultiCol a -> Rational
multiColSize MultiCol Any
forall {a}. MultiCol a
l') Rectangle
r Int
wlen
wlen :: Int
wlen = [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([a] -> Int) -> [a] -> Int
forall a b. (a -> b) -> a -> b
$ Stack a -> [a]
forall a. Stack a -> [a]
W.integrate Stack a
s
nw :: [Int]
nw = MultiCol a -> [Int]
forall a. MultiCol a -> [Int]
multiColNWin MultiCol a
l [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Int -> [Int]
forall a. a -> [a]
repeat (MultiCol a -> Int
forall a. MultiCol a -> Int
multiColDefWin MultiCol a
l)
l' :: MultiCol a
l' = MultiCol a
l { multiColNWin = take (max (length $ multiColNWin l) $ getCol (wlen-1) nw + 1) nw
, multiColActive = getCol (length $ W.up s) nw
}
resl :: Maybe (MultiCol a)
resl = if MultiCol a
forall {a}. MultiCol a
l'MultiCol a -> MultiCol a -> Bool
forall a. Eq a => a -> a -> Bool
==MultiCol a
l
then Maybe (MultiCol a)
forall a. Maybe a
Nothing
else MultiCol a -> Maybe (MultiCol a)
forall a. a -> Maybe a
Just MultiCol a
forall {a}. MultiCol a
l'
combine :: Stack a -> [b] -> [(a, b)]
combine (W.Stack a
foc [a]
left [a]
right) [b]
rs = [a] -> [b] -> [(a, b)]
forall a b. [a] -> [b] -> [(a, b)]
zip (a
foc a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a]
forall a. [a] -> [a]
reverse [a]
left [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
right) ([b] -> [(a, b)]) -> [b] -> [(a, b)]
forall a b. (a -> b) -> a -> b
$ Int -> [b] -> [b]
forall a. Int -> [a] -> [a]
raiseFocused ([a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
left) [b]
rs
handleMessage :: MultiCol a -> SomeMessage -> X (Maybe (MultiCol a))
handleMessage MultiCol a
l SomeMessage
m =
Maybe (MultiCol a) -> X (Maybe (MultiCol a))
forall a. a -> X a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (MultiCol a) -> X (Maybe (MultiCol a)))
-> Maybe (MultiCol a) -> X (Maybe (MultiCol a))
forall a b. (a -> b) -> a -> b
$ [Maybe (MultiCol a)] -> Maybe (MultiCol a)
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum [(Resize -> MultiCol a) -> Maybe Resize -> Maybe (MultiCol a)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Resize -> MultiCol a
forall {a}. Resize -> MultiCol a
resize (SomeMessage -> Maybe Resize
forall m. Message m => SomeMessage -> Maybe m
fromMessage SomeMessage
m)
,(IncMasterN -> MultiCol a)
-> Maybe IncMasterN -> Maybe (MultiCol a)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IncMasterN -> MultiCol a
forall {a}. IncMasterN -> MultiCol a
incmastern (SomeMessage -> Maybe IncMasterN
forall m. Message m => SomeMessage -> Maybe m
fromMessage SomeMessage
m)]
where resize :: Resize -> MultiCol a
resize Resize
Shrink = MultiCol a
l { multiColSize = max (-0.5) $ s-ds }
resize Resize
Expand = MultiCol a
l { multiColSize = min 1 $ s+ds }
incmastern :: IncMasterN -> MultiCol a
incmastern (IncMasterN Int
x) = MultiCol a
l { multiColNWin = take a n ++ [newval] ++ drop 1 r }
where newval :: Int
newval = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int -> (Int -> Int) -> Maybe Int -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+) ([Int] -> Maybe Int
forall a. [a] -> Maybe a
listToMaybe [Int]
r)
r :: [Int]
r = Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
drop Int
a [Int]
n
n :: [Int]
n = MultiCol a -> [Int]
forall a. MultiCol a -> [Int]
multiColNWin MultiCol a
l
ds :: Rational
ds = MultiCol a -> Rational
forall a. MultiCol a -> Rational
multiColDeltaSize MultiCol a
l
s :: Rational
s = MultiCol a -> Rational
forall a. MultiCol a -> Rational
multiColSize MultiCol a
l
a :: Int
a = MultiCol a -> Int
forall a. MultiCol a -> Int
multiColActive MultiCol a
l
description :: MultiCol a -> String
description MultiCol a
_ = String
"MultiCol"
raiseFocused :: Int -> [a] -> [a]
raiseFocused :: forall a. Int -> [a] -> [a]
raiseFocused Int
n [a]
xs = [a]
actual [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
before [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
after
where ([a]
before,[a]
rest) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
n [a]
xs
([a]
actual,[a]
after) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
1 [a]
rest
getCol :: Int -> [Int] -> Int
getCol :: Int -> [Int] -> Int
getCol Int
w (Int
n:[Int]
ns) = if Int
nInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<Int
1 Bool -> Bool -> Bool
|| Int
w Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n
then Int
0
else Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> [Int] -> Int
getCol (Int
wInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
n) [Int]
ns
getCol Int
_ [Int]
_ = -Int
1
doL :: [Int] -> Rational -> Rectangle -> Int -> [Rectangle]
doL :: [Int] -> Rational -> Rectangle -> Int -> [Rectangle]
doL [Int]
nwin Rational
s Rectangle
r Int
n = [Rectangle]
rlist
where
ncol :: Int
ncol = Int -> [Int] -> Int
getCol (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [Int]
nwin Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
size :: Int
size = Rational -> Int
forall b. Integral b => Rational -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (Rational -> Int) -> Rational -> Int
forall a b. (a -> b) -> a -> b
$ Rational -> Rational
forall a. Num a => a -> a
abs Rational
s Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Dimension -> Rational
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Rectangle -> Dimension
rect_width Rectangle
r)
c :: [Int]
c = Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take (Int
ncolInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [Int]
nwin
col :: [Int]
col = [Int]
c [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-[Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int]
c]
width :: [Int]
width
| Rational
sRational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
>Rational
0 = if Int
ncolInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
1
then [Dimension -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Dimension -> Int) -> Dimension -> Int
forall a b. (a -> b) -> a -> b
$ Rectangle -> Dimension
rect_width Rectangle
r]
else Int
sizeInt -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:Int -> Int -> [Int]
forall a. Int -> a -> [a]
replicate (Int
ncolInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) ((Dimension -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Rectangle -> Dimension
rect_width Rectangle
r) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
size) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` (Int
ncolInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1))
| Int -> Rational
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ncol Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational -> Rational
forall a. Num a => a -> a
abs Rational
s Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
>= Rational
1 = Int -> Int -> [Int]
forall a. Int -> a -> [a]
replicate Int
ncol (Int -> [Int]) -> Int -> [Int]
forall a b. (a -> b) -> a -> b
$ Dimension -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Rectangle -> Dimension
rect_width Rectangle
r) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
ncol
| Bool
otherwise = (Dimension -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Rectangle -> Dimension
rect_width Rectangle
r) Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Int
ncolInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
size)Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:Int -> Int -> [Int]
forall a. Int -> a -> [a]
replicate (Int
ncolInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
size
xpos :: [Int]
xpos = Int -> [Int] -> [Int]
forall {t}. Num t => t -> [t] -> [t]
accumEx (Position -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Position -> Int) -> Position -> Int
forall a b. (a -> b) -> a -> b
$ Rectangle -> Position
rect_x Rectangle
r) [Int]
width
accumEx :: t -> [t] -> [t]
accumEx t
a (t
x:[t]
xs) = t
at -> [t] -> [t]
forall a. a -> [a] -> [a]
:t -> [t] -> [t]
accumEx (t
at -> t -> t
forall a. Num a => a -> a -> a
+t
x) [t]
xs
accumEx t
_ [t]
_ = []
cr :: [Rectangle]
cr = (Int -> Int -> Rectangle) -> [Int] -> [Int] -> [Rectangle]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Int
x Int
w -> Rectangle
r { rect_x=fromIntegral x, rect_width=fromIntegral w }) [Int]
xpos [Int]
width
rlist :: [Rectangle]
rlist = [[Rectangle]] -> [Rectangle]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Rectangle]] -> [Rectangle]) -> [[Rectangle]] -> [Rectangle]
forall a b. (a -> b) -> a -> b
$ (Int -> Rectangle -> [Rectangle])
-> [Int] -> [Rectangle] -> [[Rectangle]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> Rectangle -> [Rectangle]
splitVertically [Int]
col [Rectangle]
cr