Safe Haskell | None |
---|---|
Language | Haskell98 |
Basic attributes interface
Attributes of an object can be get, set and constructed. For types
descending from GObject
, properties are
encoded in attributes, although attributes are slightly more
general (every property of a GObject
is an
attribute, but we can also have attributes for types not descending
from GObject
).
As an example consider a button
widget and a property (of the
Button class, or any of its parent classes or implemented
interfaces) called "label". The simplest way of getting the value
of the button is to do
value <- getButtonLabel button
And for setting:
setButtonLabel button label
This mechanism quickly becomes rather cumbersome, for example for setting the "window" property in a DOMDOMWindow in WebKit:
win <- getDOMDOMWindowWindow dom
and perhaps more importantly, one needs to chase down the type which introduces the property:
setWidgetSensitive button False
There is no setButtonSensitive
, since it is the Widget
type
that introduces the "sensitive" property.
Overloaded attributes
A much more convenient overloaded attribute resolution API is provided by this module. Getting the value of an object's attribute is straightforward:
value <- get button _label
The definition of _label
is basically a Proxy
encoding the name
of the attribute to get:
_label = fromLabelProxy (Proxy :: Proxy "label")
These proxies can be automatically generated by invoking the code
generator with the -l
option. The leading underscore is simply so
the autogenerated identifiers do not pollute the namespace, but if
this is not a concern the autogenerated names (in the autogenerated
GI/Properties.hs
) can be edited as one wishes.
In addition, for ghc >= 8.0, one can directly use the overloaded labels provided by GHC itself. Using the OverloadedLabels extension, the code above can also be written as
value <- get button #label
The syntax for setting or updating an attribute is only slightly more complex. At the simplest level it is just:
set button [ _label := value ]
or for the WebKit example above
set dom [_window := win]
However as the list notation would indicate, you can set or update multiple attributes of the same object in one go:
set button [ _label := value, _sensitive := False ]
You are not limited to setting the value of an attribute, you can also apply an update function to an attribute's value. That is the function receives the current value of the attribute and returns the new value.
set spinButton [ _value :~ (+1) ]
There are other variants of these operators, see AttrOp
below. :=>
and :~>
are like :=
and :~
but operate in the
IO
monad rather than being pure.
Attributes can also be set during construction of a
GObject
using new
button <- new Button [_label := "Can't touch this!", _sensitive := False]
In addition for value being set/get having to have the right type,
there can be attributes that are read-only, or that can only be set
during construction with new
, but cannot be
set
afterwards. That these invariants hold is also checked during
compile time.
Nullable atributes
Whenever the attribute is represented as a pointer in the C side,
it is often the case that the underlying C representation admits or
returns NULL
as a valid value for the property. In these cases
the get
operation may return a Maybe
value, with Nothing
representing the NULL
pointer value (notable exceptions are
GList
and
GSList
, for which NULL
is represented
simply as he empty list). This can be overriden in the
introspection data, since sometimes attributes are non-nullable,
even if the type would allow for NULL
.
For convenience, in nullable cases the set
operation will by
default not take a Maybe
value, but rather assume that the
caller wants to set a non-NULL
value. If setting a NULL
value
is desired, use clear
as follows
clear object _propName
Synopsis
- class AttrInfo (info :: *) where
- type AttrAllowedOps info :: [AttrOpTag]
- type AttrSetTypeConstraint info :: * -> Constraint
- type AttrBaseTypeConstraint info :: * -> Constraint
- type AttrGetType info
- type AttrLabel info :: Symbol
- type AttrOrigin info
- data AttrOpTag
- data AttrOp obj (tag :: AttrOpTag) where
- (:=) :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed tag info obj, AttrSetTypeConstraint info b) => AttrLabelProxy (attr :: Symbol) -> b -> AttrOp obj tag
- (:=>) :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed tag info obj, AttrSetTypeConstraint info b) => AttrLabelProxy (attr :: Symbol) -> IO b -> AttrOp obj tag
- (:~) :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, tag ~ AttrSet, AttrOpAllowed AttrSet info obj, AttrOpAllowed AttrGet info obj, AttrSetTypeConstraint info b, a ~ AttrGetType info) => AttrLabelProxy (attr :: Symbol) -> (a -> b) -> AttrOp obj tag
- (:~>) :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, tag ~ AttrSet, AttrOpAllowed AttrSet info obj, AttrOpAllowed AttrGet info obj, AttrSetTypeConstraint info b, a ~ AttrGetType info) => AttrLabelProxy (attr :: Symbol) -> (a -> IO b) -> AttrOp obj tag
- type family AttrOpAllowed (tag :: AttrOpTag) (info :: *) (useType :: *) :: Constraint where ...
- type AttrGetC info obj attr result = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed AttrGet info obj, result ~ AttrGetType info)
- type AttrSetC info obj attr value = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed AttrSet info obj, AttrSetTypeConstraint info value)
- type AttrConstructC info obj attr value = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed AttrConstruct info obj, AttrSetTypeConstraint info value)
- type AttrClearC info obj attr = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed AttrClear info obj)
- get :: forall info attr obj result m. (AttrGetC info obj attr result, MonadIO m) => obj -> AttrLabelProxy (attr :: Symbol) -> m result
- set :: forall o m. MonadIO m => o -> [AttrOp o AttrSet] -> m ()
- clear :: forall info attr obj m. (AttrClearC info obj attr, MonadIO m) => obj -> AttrLabelProxy (attr :: Symbol) -> m ()
- data AttrLabelProxy (a :: Symbol) = AttrLabelProxy
Documentation
class AttrInfo (info :: *) where Source #
Info describing an attribute.
type AttrAllowedOps info :: [AttrOpTag] Source #
The operations that are allowed on the attribute.
type AttrSetTypeConstraint info :: * -> Constraint Source #
Constraint on the value being set.
type AttrBaseTypeConstraint info :: * -> Constraint Source #
Constraint on the type for which we are allowed to create/set/get the attribute.
type AttrGetType info Source #
Type returned by attrGet
.
type AttrLabel info :: Symbol Source #
Name of the attribute.
type AttrOrigin info Source #
Type which introduces the attribute.
attrGet :: AttrBaseTypeConstraint info o => Proxy info -> o -> IO (AttrGetType info) Source #
Get the value of the given attribute.
attrSet :: (AttrBaseTypeConstraint info o, AttrSetTypeConstraint info b) => Proxy info -> o -> b -> IO () Source #
Set the value of the given attribute, after the object having the attribute has already been created.
attrClear :: AttrBaseTypeConstraint info o => Proxy info -> o -> IO () Source #
Set the value of the given attribute to NULL
(for nullable
attributes).
attrConstruct :: (AttrBaseTypeConstraint info o, AttrSetTypeConstraint info b) => Proxy info -> b -> IO (GValueConstruct o) Source #
Build a GValue
representing the attribute.
data AttrOp obj (tag :: AttrOpTag) where Source #
Constructors for the different operations allowed on an attribute.
(:=) :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed tag info obj, AttrSetTypeConstraint info b) => AttrLabelProxy (attr :: Symbol) -> b -> AttrOp obj tag infixr 0 | Assign a value to an attribute |
(:=>) :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed tag info obj, AttrSetTypeConstraint info b) => AttrLabelProxy (attr :: Symbol) -> IO b -> AttrOp obj tag infixr 0 | Assign the result of an IO action to an attribute |
(:~) :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, tag ~ AttrSet, AttrOpAllowed AttrSet info obj, AttrOpAllowed AttrGet info obj, AttrSetTypeConstraint info b, a ~ AttrGetType info) => AttrLabelProxy (attr :: Symbol) -> (a -> b) -> AttrOp obj tag infixr 0 | Apply an update function to an attribute |
(:~>) :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, tag ~ AttrSet, AttrOpAllowed AttrSet info obj, AttrOpAllowed AttrGet info obj, AttrSetTypeConstraint info b, a ~ AttrGetType info) => AttrLabelProxy (attr :: Symbol) -> (a -> IO b) -> AttrOp obj tag infixr 0 | Apply an IO update function to an attribute |
type family AttrOpAllowed (tag :: AttrOpTag) (info :: *) (useType :: *) :: Constraint where ... Source #
Whether a given AttrOpTag
is allowed on an attribute, given the
info type.
AttrOpAllowed tag info useType = AttrOpIsAllowed tag (AttrAllowedOps info) (AttrLabel info) (AttrOrigin info) useType ~ OpIsAllowed |
type AttrGetC info obj attr result = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed AttrGet info obj, result ~ AttrGetType info) Source #
Constraints on a obj
/attr
pair so get
is possible,
producing a value of type result
.
type AttrSetC info obj attr value = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed AttrSet info obj, AttrSetTypeConstraint info value) Source #
Constraint on a obj
/attr
pair so that set
works on values
of type value
.
type AttrConstructC info obj attr value = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed AttrConstruct info obj, AttrSetTypeConstraint info value) Source #
Constraint on a obj
/value
pair so that new
works on values
of type @value
.
type AttrClearC info obj attr = (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed AttrClear info obj) Source #
Constraint on a obj
/attr
pair so that clear
is allowed.
get :: forall info attr obj result m. (AttrGetC info obj attr result, MonadIO m) => obj -> AttrLabelProxy (attr :: Symbol) -> m result Source #
Get the value of an attribute for an object.
set :: forall o m. MonadIO m => o -> [AttrOp o AttrSet] -> m () Source #
Set a number of properties for some object.
clear :: forall info attr obj m. (AttrClearC info obj attr, MonadIO m) => obj -> AttrLabelProxy (attr :: Symbol) -> m () Source #
Set a nullable attribute to NULL
.
data AttrLabelProxy (a :: Symbol) Source #
A proxy for attribute labels.
Instances
a ~ x => IsLabel x (AttrLabelProxy a) Source # | |
fromLabel :: AttrLabelProxy a # | |
a ~ x => IsLabelProxy x (AttrLabelProxy a) Source # | Support for overloaded labels. |
fromLabelProxy :: Proxy x -> AttrLabelProxy a Source # |