module Graphics.UI.Frame.Panes (
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)
type PanePath = [PanePathElement]
data PanePathElement = SplitP PaneDirection | GroupP Text
deriving (Eq,Show,Read)
data PaneDirection = TopP | BottomP | LeftP | RightP
deriving (Eq,Show,Read)
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)
class (Typeable alpha, PaneMonad delta) => Pane alpha delta | alpha -> delta where
getTopWidget :: alpha -> Widget
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)
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)