module Yi.Tab
(
Tab,
TabRef,
tabWindowsA,
tabLayoutManagerA,
tabDividerPositionA,
tkey,
tabMiniWindows,
tabFocus,
forceTab,
mapWindows,
tabLayout,
tabFoldl,
makeTab,
makeTab1,
) where
import Prelude hiding (foldr, foldl)
import Control.Lens
import qualified Data.Binary as Binary
import Data.Default
import Data.Typeable
import Data.Foldable
import qualified Data.List.PointedList as PL
import Control.Applicative
import Yi.Buffer.Basic(WindowRef)
import Yi.Layout
import Yi.Window
type TabRef = Int
data Tab = Tab {
tkey :: !TabRef,
tabWindows :: !(PL.PointedList Window),
tabLayout :: !(Layout WindowRef),
tabLayoutManager :: !AnyLayoutManager
}
deriving Typeable
tabFocus :: Tab -> Window
tabFocus = PL._focus . tabWindows
tabMiniWindows :: Tab -> [Window]
tabMiniWindows = Prelude.filter isMini . toList . tabWindows
tabWindowsA :: Functor f =>
(PL.PointedList Window -> f (PL.PointedList Window)) -> Tab -> f Tab
tabWindowsA f s = (`setter` s) <$> f (getter s)
where
setter ws t = relayoutIf (toList ws /= toList (tabWindows t)) (t { tabWindows = ws})
getter = tabWindows
tabLayoutManagerA :: Functor f =>
(AnyLayoutManager -> f AnyLayoutManager) -> Tab -> f Tab
tabLayoutManagerA f s = (`setter` s) <$> f (getter s)
where
setter lm t = relayoutIf (lm /= tabLayoutManager t) (t { tabLayoutManager = lm })
getter = tabLayoutManager
tabDividerPositionA :: DividerRef -> Lens' Tab DividerPosition
tabDividerPositionA ref = lens tabLayout (\ t l -> t{tabLayout = l}) . dividerPositionA ref
relayoutIf :: Bool -> Tab -> Tab
relayoutIf False t = t
relayoutIf True t = relayout t
relayout :: Tab -> Tab
relayout t = t { tabLayout = buildLayout (tabWindows t) (tabLayoutManager t) (tabLayout t) }
instance Binary.Binary Tab where
put (Tab tk ws _ _) = Binary.put tk >> Binary.put ws
get = makeTab <$> Binary.get <*> Binary.get
instance Eq Tab where
(==) t1 t2 = tkey t1 == tkey t2
instance Show Tab where
show t = "Tab " ++ show (tkey t)
mapWindows :: (Window -> Window) -> Tab -> Tab
mapWindows f = over tabWindowsA (fmap f)
forceTab :: Tab -> Tab
forceTab t = foldr seq t (t ^. tabWindowsA)
tabFoldl :: (a -> Window -> a) -> a -> Tab -> a
tabFoldl f z t = foldl f z (t ^. tabWindowsA)
buildLayout :: PL.PointedList Window -> AnyLayoutManager -> Layout WindowRef -> Layout WindowRef
buildLayout ws m l = pureLayout m l . fmap wkey . Prelude.filter (not . isMini) . toList $ ws
makeTab :: TabRef -> PL.PointedList Window -> Tab
makeTab key ws = Tab key ws (buildLayout ws def def) def
makeTab1 :: TabRef -> Window -> Tab
makeTab1 key win = makeTab key (PL.singleton win)