{-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors -fno-warn-orphans #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} -- | Implementation of 'Gtk.Paned' as a declarative container. module GI.Gtk.Declarative.Container.Paned ( Pane , PaneProperties (..) , defaultPaneProperties , pane , paned ) where import Data.Coerce (coerce) import Data.Typeable import Data.Vector (Vector) import qualified Data.Vector as Vector import GHC.Ptr (nullPtr) import qualified GI.GLib as GLib import qualified GI.Gtk as Gtk import GI.Gtk.Declarative.Attributes import GI.Gtk.Declarative.Container import GI.Gtk.Declarative.Container.Class import GI.Gtk.Declarative.EventSource import GI.Gtk.Declarative.Patch import GI.Gtk.Declarative.Widget -- | Describes a pane to be packed with -- 'Gtk.panePack1'/'Gtk.panePack2' in a 'Gtk.Paned'. data Pane event = Pane { paneProperties :: PaneProperties , paneChild :: Widget event } deriving (Functor) -- | Values used when packing a pane into a 'Gtk.Paned'. data PaneProperties = PaneProperties { resize :: Bool , shrink :: Bool } -- | Defaults for 'PaneProperties'. Use these and override specific -- fields. defaultPaneProperties :: PaneProperties defaultPaneProperties = PaneProperties {resize = False, shrink = True} -- | Construct a pane to be packed with -- 'Gtk.panePack1'/'Gtk.panePack2' in a 'Gtk.Paned'. pane :: PaneProperties -> Widget event -> Pane event pane paneProperties paneChild = Pane {..} instance Patchable Pane where create = create . paneChild patch s b1 b2 = patch s (paneChild b1) (paneChild b2) instance EventSource Pane where subscribe Pane{..} = subscribe paneChild -- | Construct a 'Gtk.Paned' based on attributes and two child 'Pane's. paned :: Typeable event => Vector (Attribute Gtk.Paned event) -> Pane event -> Pane event -> Widget event paned attrs p1 p2 = container Gtk.Paned attrs (Panes p1 p2) data Panes child = Panes child child deriving (Functor) instance IsContainer Gtk.Paned Pane where appendChild paned' Pane{paneProperties = PaneProperties{resize, shrink}} widget' = do c1 <- Gtk.panedGetChild1 paned' c2 <- Gtk.panedGetChild2 paned' case (c1, c2) of (Nothing, Nothing) -> Gtk.panedPack1 paned' widget' (coerce resize) (coerce shrink) (Just _, Nothing) -> Gtk.panedPack2 paned' widget' (coerce resize) (coerce shrink) _ -> GLib.logDefaultHandler (Just "gi-gtk-declarative") [GLib.LogLevelFlagsLevelWarning] (Just "appendChild: The `GI.Gtk.Paned` widget can only fit 2 panes. Additional children will be ignored.") nullPtr replaceChild paned' Pane{paneProperties = PaneProperties{resize, shrink}} i old new = do Gtk.widgetDestroy old case i of 0 -> Gtk.panedPack1 paned' new (coerce resize) (coerce shrink) 1 -> Gtk.panedPack2 paned' new (coerce resize) (coerce shrink) _ -> GLib.logDefaultHandler (Just "gi-gtk-declarative") [GLib.LogLevelFlagsLevelWarning] (Just "replaceChild: The `GI.Gtk.Paned` widget can only fit 2 panes. Additional children will be ignored.") nullPtr instance ToChildren Gtk.Paned Panes Pane where toChildren _ (Panes p1 p2) = Children (Vector.fromList [p1, p2])