gi-gtk-declarative-0.2.0: src/GI/Gtk/Declarative/State.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
-- | The 'StateTree' and 'SomeState' form a "shadow state"
-- representation, used in patching. Declarative widgets can return,
-- and later on reuse, its underlying GTK+ widget, collected
-- properties and classes, style context, custom internal state, and
-- child states. This reduces the need for querying GTK+ widgets
-- excessively, and recalculating/resetting, greatly improving the
-- performance of patching.
module GI.Gtk.Declarative.State where
import Data.Typeable
import Data.Vector (Vector)
import qualified GI.Gtk as Gtk
import GI.Gtk.Declarative.Attributes.Collected
import GI.Gtk.Declarative.Container.Class
-- | A 'Data.Dynamic.Dynamic'-like container of a 'StateTree' value.
data SomeState where
SomeState
:: ( Gtk.IsWidget widget
, Typeable widget
, Typeable customState
)
=> StateTree stateType widget child event customState
-> SomeState
-- | The types of state trees that are available, matching the types
-- of GTK+ widgets (single widget, bin, and container.)
data StateType = WidgetState | BinState | ContainerState
-- | A state tree for a specific 'widget'. This is built up recursively
-- to contain child state trees, for bin and container child widgets.
data StateTree (stateType :: StateType) widget child event customState where
StateTreeWidget
:: !(StateTreeNode widget event customState)
-> StateTree 'WidgetState widget child event customState
StateTreeBin
:: !(StateTreeNode widget event customState)
-> SomeState
-> StateTree 'BinState widget child event customState
StateTreeContainer
:: ( Gtk.IsContainer widget
, IsContainer widget child
)
=> !(StateTreeNode widget event customState)
-> Vector SomeState
-> StateTree 'ContainerState widget child event customState
-- | The common structure for all state tree nodes.
data StateTreeNode widget event customState = StateTreeNode
{ stateTreeWidget :: !widget
, stateTreeStyleContext :: !Gtk.StyleContext
, stateTreeCollectedAttributes :: !(Collected widget event)
, stateTreeCustomState :: customState
}
-- * Convenience accessor functions
-- | Get the common state tree node information.
stateTreeNode
:: StateTree stateType widget child event customState
-> StateTreeNode widget event customState
stateTreeNode (StateTreeWidget s ) = s
stateTreeNode (StateTreeBin s _) = s
stateTreeNode (StateTreeContainer s _) = s
-- | Get the specific type of GTK+ widget of a state tree.
stateTreeNodeWidget :: StateTree stateType widget child event customState -> widget
stateTreeNodeWidget = stateTreeWidget . stateTreeNode
-- | Get the GTK+ widget, cast to 'Gtk.Widget', of /some/ state tree.
someStateWidget :: SomeState -> IO Gtk.Widget
someStateWidget (SomeState st) = Gtk.toWidget (stateTreeNodeWidget st)