content: {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
  {-# LANGUAGE MultiParamTypeClasses, Rank2Types, TypeFamilies #-}
  
  -----------------------------------------------------------------------------
  -- |
  -- Module      :  XMonad.Layout.Groups.Examples
  -- Copyright   :  Quentin Moser <moserq@gmail.com>
  -- License     :  BSD-style (see LICENSE)
  --
  -- Maintainer  :  orphaned
  -- Stability   :  unstable
  -- Portability :  unportable
  --
  -- Example layouts for "XMonad.Layout.Groups".
  --
  -----------------------------------------------------------------------------
  
  module XMonad.Layout.Groups.Examples ( -- * Usage
                                         -- $usage
  
                                         -- * Example: Row of columns
                                         -- $example1
                                         rowOfColumns
                                       , zoomColumnIn
                                       , zoomColumnOut
                                       , zoomColumnReset
                                       , toggleColumnFull
                                       , zoomWindowIn
                                       , zoomWindowOut
                                       , zoomWindowReset
                                       , toggleWindowFull
  
                                         -- * Example: Tiled tab groups
                                         -- $example2
                                       , tallTabs
                                       , mirrorTallTabs
                                       , fullTabs
                                       , TiledTabsConfig(..)
                                       , def
                                       , defaultTiledTabsConfig
                                       , increaseNMasterGroups
                                       , decreaseNMasterGroups
                                       , shrinkMasterGroups
                                       , expandMasterGroups
                                       , nextOuterLayout
  
  
                                         -- * Useful re-exports and utils
                                       , module XMonad.Layout.Groups.Helpers
                                       , shrinkText
                                       , defaultTheme
                                       , GroupEQ(..)
                                       , zoomRowG
                                       ) where
  
  import XMonad hiding ((|||))
  
  import qualified XMonad.Layout.Groups as G
  import XMonad.Layout.Groups.Helpers
  
  import XMonad.Layout.ZoomRow
  import XMonad.Layout.Tabbed
  import XMonad.Layout.Named
  import XMonad.Layout.Renamed
  import XMonad.Layout.LayoutCombinators
  import XMonad.Layout.Decoration
  import XMonad.Layout.Simplest
  
  
  -- $usage
  -- This module contains example 'G.Groups'-based layouts.
  -- You can either import this module directly, or look at its source
  -- for ideas of how "XMonad.Layout.Groups" may be used.
  --
  -- You can use the contents of this module by adding
  --
  -- > import XMonad.Layout.Groups.Examples
  --
  -- to the top of your @.\/.xmonad\/xmonad.hs@.
  --
  -- For more information on using any of the layouts, jump directly
  --   to its \"Example\" section.
  --
  -- Whichever layout you choose to use, you will probably want to be
  --   able to move focus and windows between groups in a consistent
  --   manner. For this, you should take a look at the functions from
  --   the "XMonad.Layout.Groups.Helpers" module, which are all
  --   re-exported by this module.
  --
  -- For more information on how to extend your layour hook and key bindings, see
  --   "XMonad.Doc.Extending".
  
  
  -- * Helper: ZoomRow of Group elements
  
  -- | Compare two 'Group's by comparing the ids of their layouts.
  data GroupEQ a = GroupEQ
    deriving (Show, Read)
  
  instance Eq a => EQF GroupEQ (G.Group l a) where
      eq _ (G.G l1 _) (G.G l2 _) = G.sameID l1 l2
  
  zoomRowG :: (Eq a, Show a, Read a, Show (l a), Read (l a))
              => ZoomRow GroupEQ (G.Group l a)
  zoomRowG = zoomRowWith GroupEQ
  
  
  -- * Example 1: Row of columns
  
  -- $example1
  -- A layout that arranges windows in a row of columns. It uses 'ZoomRow's for
  -- both, allowing you to:
  --
  --  * Freely change the proportion of the screen width allocated to each column
  --
  --  * Freely change the proportion of a column's heigth allocated to each of its windows
  --
  --  * Set a column to occupy the whole screen space whenever it has focus
  --
  --  * Set a window to occupy its whole column whenever it has focus
  --
  -- to use this layout, add 'rowOfColumns' to your layout hook, for example:
  --
  -- > myLayout = rowOfColumns
  --
  -- To be able to change the sizes of columns and windows, you can create key bindings
  -- for the relevant actions:
  --
  -- > ((modMask, xK_minus), zoomWindowOut)
  --
  -- and so on.
  
  rowOfColumns = G.group column zoomRowG
      where column = renamed [CutWordsLeft 2, PrependWords "ZoomColumn"] $ Mirror zoomRow
  
  -- | Increase the width of the focused column
  zoomColumnIn :: X ()
  zoomColumnIn = sendMessage $ G.ToEnclosing $ SomeMessage $ zoomIn
  
  -- | Decrease the width of the focused column
  zoomColumnOut :: X ()
  zoomColumnOut = sendMessage $ G.ToEnclosing $ SomeMessage $ zoomOut
  
  -- | Reset the width of the focused column
  zoomColumnReset :: X ()
  zoomColumnReset = sendMessage $ G.ToEnclosing $ SomeMessage $ zoomReset
  
  -- | Toggle whether the currently focused column should
  -- take up all available space whenever it has focus
  toggleColumnFull :: X ()
  toggleColumnFull = sendMessage $ G.ToEnclosing $ SomeMessage $ ZoomFullToggle
  
  -- | Increase the heigth of the focused window
  zoomWindowIn :: X ()
  zoomWindowIn = sendMessage zoomIn
  
  -- | Decrease the height of the focused window
  zoomWindowOut :: X ()
  zoomWindowOut = sendMessage zoomOut
  
  -- | Reset the height of the focused window
  zoomWindowReset :: X ()
  zoomWindowReset = sendMessage zoomReset
  
  -- | Toggle whether the currently focused window should
  -- take up the whole column whenever it has focus
  toggleWindowFull :: X ()
  toggleWindowFull = sendMessage ZoomFullToggle
  
  
  -- * Example 2: Tabbed groups in a Tall/Full layout.
  
  -- $example2
  -- A layout which arranges windows into tabbed groups, and the groups
  -- themselves according to XMonad's default algorithm
  -- (@'Tall' ||| 'Mirror' 'Tall' ||| 'Full'@). As their names
  -- indicate, 'tallTabs' starts as 'Tall', 'mirrorTallTabs' starts
  -- as 'Mirror' 'Tall' and 'fullTabs' starts as 'Full', but in any
  -- case you can freely switch between the three afterwards.
  --
  -- You can use any of these three layouts by including it in your layout hook.
  -- You will need to provide it with a 'TiledTabsConfig' containing the size
  -- parameters for 'Tall' and 'Mirror' 'Tall', and the shrinker and decoration theme
  -- for the tabs. If you're happy with defaults, you can use 'def':
  --
  -- > myLayout = tallTabs def
  --
  -- To be able to increase\/decrease the number of master groups and shrink\/expand
  -- the master area, you can create key bindings for the relevant actions:
  --
  -- > ((modMask, xK_h), shrinkMasterGroups)
  --
  -- and so on.
  
  -- | Configuration data for the "tiled tab groups" layout
  data TiledTabsConfig s = TTC { vNMaster :: Int
                               , vRatio :: Rational
                               , vIncrement :: Rational
                               , hNMaster :: Int
                               , hRatio :: Rational
                               , hIncrement :: Rational
                               , tabsShrinker :: s
                               , tabsTheme :: Theme }
  
  instance s ~ DefaultShrinker => Default (TiledTabsConfig s) where
      def = TTC 1 0.5 (3/100) 1 0.5 (3/100) shrinkText def
  
  {-# DEPRECATED defaultTiledTabsConfig "Use def (from Data.Default, and re-exported by XMonad.Layout.Groups) instead." #-}
  defaultTiledTabsConfig :: TiledTabsConfig DefaultShrinker
  defaultTiledTabsConfig = def
  
  fullTabs c = _tab c $ G.group _tabs $ Full ||| _vert c ||| _horiz c
  
  tallTabs c = _tab c $ G.group _tabs $ _vert c ||| _horiz c ||| Full
  
  mirrorTallTabs c = _tab c $ G.group _tabs $ _horiz c ||| Full ||| _vert c
  
  _tabs = named "Tabs" Simplest
  
  _tab c l = renamed [CutWordsLeft 1] $ addTabs (tabsShrinker c) (tabsTheme c) l
  
  _vert c = named "Vertical" $ Tall (vNMaster c) (vIncrement c) (vRatio c)
  
  _horiz c = named "Horizontal" $ Mirror $ Tall (hNMaster c) (hIncrement c) (hRatio c)
  
  -- | Increase the number of master groups by one
  increaseNMasterGroups :: X ()
  increaseNMasterGroups = sendMessage $ G.ToEnclosing $ SomeMessage $ IncMasterN 1
  
  -- | Decrease the number of master groups by one
  decreaseNMasterGroups :: X ()
  decreaseNMasterGroups = sendMessage $ G.ToEnclosing $ SomeMessage $ IncMasterN (-1)
  
  -- | Shrink the master area
  shrinkMasterGroups :: X ()
  shrinkMasterGroups = sendMessage $ G.ToEnclosing $ SomeMessage $ Shrink
  
  -- | Expand the master area
  expandMasterGroups :: X ()
  expandMasterGroups = sendMessage $ G.ToEnclosing $ SomeMessage $ Expand
  
  -- | Rotate the available outer layout algorithms
  nextOuterLayout :: X ()
  nextOuterLayout = sendMessage $ G.ToEnclosing $ SomeMessage $ NextLayout
  