{-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE OverloadedStrings #-} ----------------------------------------------------------------------------- -- -- Module : IDE.Core.Panes -- Copyright : (c) Juergen Nicklisch-Franken, Hamish Mackenzie -- License : GNU-GPL -- -- Maintainer : -- Stability : provisional21 -- Portability : portable -- -- | The basic definitions for all panes -- ------------------------------------------------------------------------------- module Graphics.UI.Frame.Panes ( -- * Panes and pane layout PaneMonad(..) , IDEPane(..) , Pane(..) , RecoverablePane(..) , PaneDirection(..) , PanePathElement(..) , PanePath , PaneLayout(..) , PaneName , Connection(..) , Connections , StandardPath , FrameState(..) , signalDisconnectAll ) where import Graphics.UI.Gtk hiding (get) import System.Glib.GObject import System.Glib.Signals import Data.Maybe import Data.Map (Map) import qualified Data.Map as Map import Data.Typeable import Graphics.UI.Editor.Basics (Connection(..), Connection, Connections) import Control.Monad.IO.Class (MonadIO) import Data.Text (Text) import Data.Monoid ((<>)) import qualified Data.Text as T (pack) -- --------------------------------------------------------------------- -- Panes and pane layout -- -- -- | A path to a pane -- type PanePath = [PanePathElement] -- -- | An element of a path to a pane -- data PanePathElement = SplitP PaneDirection | GroupP Text deriving (Eq,Show,Read) -- -- | The relative direction to a pane from the parent -- data PaneDirection = TopP | BottomP | LeftP | RightP deriving (Eq,Show,Read) -- -- | Description of a window layout -- Horizontal: top bottom Vertical: left right -- data PaneLayout = HorizontalP PaneLayout PaneLayout Int | VerticalP PaneLayout PaneLayout Int | TerminalP { paneGroups :: Map Text PaneLayout , paneTabs :: Maybe PaneDirection , currentPage :: Int , detachedId :: Maybe Text , detachedSize :: Maybe (Int, Int) } deriving (Eq,Show,Read) -- -- | All kinds of panes are instances of pane -- class (Typeable alpha, PaneMonad delta) => Pane alpha delta | alpha -> delta where getTopWidget :: alpha -> Widget -- ^ gets the top Widget of this pane paneId :: alpha -> Text primPaneName :: alpha -> Text paneName :: alpha -> PaneName paneName b = if getAddedIndex b == 0 then primPaneName b else primPaneName b <> "(" <> T.pack (show $ getAddedIndex b) <> ")" getAddedIndex :: alpha -> Int getAddedIndex _ = 0 class (Pane alpha delta, Typeable beta, Show beta, Read beta) => RecoverablePane alpha beta delta | beta -> alpha, alpha -> beta where saveState :: alpha -> delta (Maybe beta) recoverState :: PanePath -> beta -> delta (Maybe alpha) builder :: PanePath -> Notebook -> Window -> delta (Maybe alpha,Connections) -- getEditor :: Editor alpha makeActive :: alpha -> delta () makeActive pane = activateThisPane pane [] closePane :: alpha -> delta Bool closePane = closeThisPane getPane :: delta (Maybe alpha) getPane = getThisPane forceGetPane :: Either PanePath Text -> delta alpha forceGetPane pp = do mbPane <- getOrBuildPane pp case mbPane of Nothing -> error "Can't get pane " Just p -> return p getOrBuildPane :: Either PanePath Text -> delta (Maybe alpha) getOrBuildPane = getOrBuildThisPane displayPane :: alpha -> Bool -> delta () displayPane = displayThisPane getAndDisplayPane :: Either PanePath Text -> Bool -> delta (Maybe alpha) getAndDisplayPane pps b = do mbP <- getOrBuildThisPane pps case mbP of Nothing -> return Nothing Just p -> do displayPane p b return (Just p) buildPane :: PanePath -> Notebook -> (PanePath -> Notebook -> Window -> delta (Maybe alpha,Connections)) -> delta (Maybe alpha) buildPane = buildThisPane class MonadIO delta => PaneMonad delta where setFrameState :: FrameState delta -> delta () getFrameState :: delta (FrameState delta) runInIO :: forall alpha beta. (beta -> delta alpha) -> delta (beta -> IO alpha) panePathForGroup:: Text -> delta PanePath getThisPane :: forall alpha beta . RecoverablePane alpha beta delta => delta (Maybe alpha) displayThisPane :: forall alpha beta . RecoverablePane alpha beta delta => alpha -> Bool -> delta () getOrBuildThisPane :: forall alpha beta . RecoverablePane alpha beta delta => Either PanePath Text -> delta (Maybe alpha) buildThisPane :: forall alpha beta . RecoverablePane alpha beta delta => PanePath -> Notebook -> (PanePath -> Notebook -> Window -> delta (Maybe alpha,Connections)) -> delta (Maybe alpha) activateThisPane :: forall alpha beta . RecoverablePane alpha beta delta => alpha -> Connections -> delta () closeThisPane :: forall alpha beta . RecoverablePane alpha beta delta => alpha -> delta Bool type PaneName = Text data IDEPane delta = forall alpha beta. (RecoverablePane alpha beta delta) => PaneC alpha instance Eq (IDEPane delta) where (==) (PaneC x) (PaneC y) = paneName x == paneName y instance Ord (IDEPane delta) where (<=) (PaneC x) (PaneC y) = paneName x <= paneName y instance Show (IDEPane delta) where show (PaneC x) = show $ "Pane " <> paneName x type StandardPath = PanePath data FrameState delta = FrameState { windows :: [Window] , uiManager :: UIManager , panes :: Map PaneName (IDEPane delta) , paneMap :: Map PaneName (PanePath, Connections) , activePane :: Maybe (PaneName, Connections) , panePathFromNB :: ! (Map Notebook PanePath) , layout :: PaneLayout} deriving Show instance Show Window where show _ = "a Window" instance Show UIManager where show _ = "a UIManager" instance Show Connection where show _ = "a Connection" instance Show Notebook where show _ = "a Notebook" signalDisconnectAll :: Connections -> IO () signalDisconnectAll = mapM_ (\ (ConnectC s) -> signalDisconnect s)