    {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Layout.TwoPane
    -- Description :  A layout that splits the screen horizontally and shows two windows.
    -- Copyright   :  (c) Spencer Janssen <spencerjanssen@gmail.com>
    -- License     :  BSD3-style (see LICENSE)
    --
    -- Maintainer  :  Spencer Janssen <spencerjanssen@gmail.com>
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- A layout that splits the screen horizontally and shows two windows.  The
    -- left window is always the master window, and the right is either the
    -- currently focused window or the second window in layout order.
    --
    -----------------------------------------------------------------------------

    module XMonad.Layout.TwoPane (
                                  -- * Usage
                                  -- $usage
                                  TwoPane (..)
                                 ) where

    import XMonad hiding (focus)
    import XMonad.StackSet ( focus, up, down)

    -- $usage
    -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
    --
    -- > import XMonad.Layout.TwoPane
    --
    -- Then edit your @layoutHook@ by adding the TwoPane layout:
    --
    -- > myLayout = TwoPane (3/100) (1/2)  ||| Full ||| etc..
    -- > main = xmonad def { layoutHook = myLayout }
    --
    -- For more detailed instructions on editing the layoutHook see:
    --
    -- "XMonad.Doc.Extending#Editing_the_layout_hook"

    data TwoPane a =
        TwoPane Rational Rational
        deriving ( Int -> TwoPane a -> ShowS
    [TwoPane a] -> ShowS
    TwoPane a -> String
    (Int -> TwoPane a -> ShowS)
    -> (TwoPane a -> String)
    -> ([TwoPane a] -> ShowS)
    -> Show (TwoPane a)
    forall a. Int -> TwoPane a -> ShowS
    forall a. [TwoPane a] -> ShowS
    forall a. TwoPane a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Int -> TwoPane a -> ShowS
    showsPrec :: Int -> TwoPane a -> ShowS
    $cshow :: forall a. TwoPane a -> String
    show :: TwoPane a -> String
    $cshowList :: forall a. [TwoPane a] -> ShowS
    showList :: [TwoPane a] -> ShowS
    Show, ReadPrec [TwoPane a]
    ReadPrec (TwoPane a)
    Int -> ReadS (TwoPane a)
    ReadS [TwoPane a]
    (Int -> ReadS (TwoPane a))
    -> ReadS [TwoPane a]
    -> ReadPrec (TwoPane a)
    -> ReadPrec [TwoPane a]
    -> Read (TwoPane a)
    forall a. ReadPrec [TwoPane a]
    forall a. ReadPrec (TwoPane a)
    forall a. Int -> ReadS (TwoPane a)
    forall a. ReadS [TwoPane a]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: forall a. Int -> ReadS (TwoPane a)
    readsPrec :: Int -> ReadS (TwoPane a)
    $creadList :: forall a. ReadS [TwoPane a]
    readList :: ReadS [TwoPane a]
    $creadPrec :: forall a. ReadPrec (TwoPane a)
    readPrec :: ReadPrec (TwoPane a)
    $creadListPrec :: forall a. ReadPrec [TwoPane a]
    readListPrec :: ReadPrec [TwoPane a]
    Read )

    instance LayoutClass TwoPane a where
        doLayout :: TwoPane a
    -> Rectangle -> Stack a -> X ([(a, Rectangle)], Maybe (TwoPane a))
    doLayout (TwoPane Rational
    _ Rational
    split) Rectangle
    r Stack a
    s = ([(a, Rectangle)], Maybe (TwoPane a))
    -> X ([(a, Rectangle)], Maybe (TwoPane a))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Rectangle -> Stack a -> [(a, Rectangle)]
    forall {a}. Rectangle -> Stack a -> [(a, Rectangle)]
    arrange Rectangle
    r Stack a
    s,Maybe (TwoPane a)
    forall a. Maybe a
    Nothing)
            where
              arrange :: Rectangle -> Stack a -> [(a, Rectangle)]
    arrange Rectangle
    rect Stack a
    st = case [a] -> [a]
    forall a. [a] -> [a]
    reverse (Stack a -> [a]
    forall a. Stack a -> [a]
    up Stack a
    st) of
                                  (a
    master:[a]
    _) -> [(a
    master,Rectangle
    left),(Stack a -> a
    forall a. Stack a -> a
    focus Stack a
    st,Rectangle
    right)]
                                  [] -> case Stack a -> [a]
    forall a. Stack a -> [a]
    down Stack a
    st of
                                          (a
    next:[a]
    _) -> [(Stack a -> a
    forall a. Stack a -> a
    focus Stack a
    st,Rectangle
    left),(a
    next,Rectangle
    right)]
                                          [] -> [(Stack a -> a
    forall a. Stack a -> a
    focus Stack a
    st, Rectangle
    rect)]
                  where (Rectangle
    left, Rectangle
    right) = Rational -> Rectangle -> (Rectangle, Rectangle)
    forall r. RealFrac r => r -> Rectangle -> (Rectangle, Rectangle)
    splitHorizontallyBy Rational
    split Rectangle
    rect

        handleMessage :: TwoPane a -> SomeMessage -> X (Maybe (TwoPane a))
    handleMessage (TwoPane Rational
    delta Rational
    split) SomeMessage
    x =
            Maybe (TwoPane a) -> X (Maybe (TwoPane a))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (TwoPane a) -> X (Maybe (TwoPane a)))
    -> Maybe (TwoPane a) -> X (Maybe (TwoPane a))
    forall a b. (a -> b) -> a -> b
    $ case SomeMessage -> Maybe Resize
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    x of
                       Just Resize
    Shrink -> TwoPane a -> Maybe (TwoPane a)
    forall a. a -> Maybe a
    Just (Rational -> Rational -> TwoPane a
    forall a. Rational -> Rational -> TwoPane a
    TwoPane Rational
    delta (Rational
    split Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    - Rational
    delta))
                       Just Resize
    Expand -> TwoPane a -> Maybe (TwoPane a)
    forall a. a -> Maybe a
    Just (Rational -> Rational -> TwoPane a
    forall a. Rational -> Rational -> TwoPane a
    TwoPane Rational
    delta (Rational
    split Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    + Rational
    delta))
                       Maybe Resize
    _           -> Maybe (TwoPane a)
    forall a. Maybe a
    Nothing

        description :: TwoPane a -> String
    description TwoPane a
    _ = String
    "TwoPane"