Safe Haskell | None |
---|---|
Language | Haskell2010 |
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
).
If you're wondering what the possible attributes of a GObject are,
look at the list of properties in the documentation, e.g. the
Properties heading of the docs for Button
lists
properties such as image
and relief
. Parent classes may also
introduce properties, so since a Button is an instance of
IsActionable
, it inherits properties like actionName
from
Actionable
too.
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 AttrBaseTypeConstraint info :: * -> Constraint
- type AttrGetType info
- type AttrSetTypeConstraint info :: * -> Constraint
- type AttrTransferTypeConstraint info :: * -> Constraint
- type AttrTransferType info :: *
- type AttrLabel info :: Symbol
- type AttrOrigin info
- attrGet :: AttrBaseTypeConstraint info o => o -> IO (AttrGetType info)
- attrSet :: (AttrBaseTypeConstraint info o, AttrSetTypeConstraint info b) => o -> b -> IO ()
- attrClear :: AttrBaseTypeConstraint info o => o -> IO ()
- attrConstruct :: (AttrBaseTypeConstraint info o, AttrSetTypeConstraint info b) => b -> IO (GValueConstruct o)
- attrTransfer :: forall o b. (AttrBaseTypeConstraint info o, AttrTransferTypeConstraint info b) => Proxy o -> b -> IO (AttrTransferType 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
- (:&=) :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed tag info obj, AttrTransferTypeConstraint info b, AttrSetTypeConstraint info (AttrTransferType info)) => AttrLabelProxy (attr :: Symbol) -> 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.
Nothing
type AttrAllowedOps info :: [AttrOpTag] Source #
The operations that are allowed on the attribute.
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 AttrSetTypeConstraint info :: * -> Constraint Source #
Constraint on the value being set.
type AttrSetTypeConstraint info = (~) (AttrGetType info) Source #
type AttrTransferTypeConstraint info :: * -> Constraint Source #
Constraint on the value being set, with allocation allowed
(see :&=
below).
type AttrTransferTypeConstraint info = (~) (AttrTransferType info) Source #
type AttrTransferType info :: * Source #
Type resulting from the allocation.
type AttrTransferType info = AttrGetType info Source #
type AttrLabel info :: Symbol Source #
Name of the attribute.
type AttrOrigin info Source #
Type which introduces the attribute.
attrGet :: AttrBaseTypeConstraint info o => o -> IO (AttrGetType info) Source #
Get the value of the given attribute.
default attrGet :: CheckNotElem 'AttrGet (AttrAllowedOps info) (GetNotProvidedError info) => o -> IO (AttrGetType info) Source #
attrSet :: (AttrBaseTypeConstraint info o, AttrSetTypeConstraint info b) => o -> b -> IO () Source #
Set the value of the given attribute, after the object having the attribute has already been created.
default attrSet :: CheckNotElem 'AttrSet (AttrAllowedOps info) (SetNotProvidedError info) => o -> b -> IO () Source #
attrClear :: AttrBaseTypeConstraint info o => o -> IO () Source #
Set the value of the given attribute to NULL
(for nullable
attributes).
default attrClear :: CheckNotElem 'AttrClear (AttrAllowedOps info) (ClearNotProvidedError info) => o -> IO () Source #
attrConstruct :: (AttrBaseTypeConstraint info o, AttrSetTypeConstraint info b) => b -> IO (GValueConstruct o) Source #
Build a GValue
representing the attribute.
default attrConstruct :: CheckNotElem 'AttrConstruct (AttrAllowedOps info) (ConstructNotProvidedError info) => b -> IO (GValueConstruct o) Source #
attrTransfer :: forall o b. (AttrBaseTypeConstraint info o, AttrTransferTypeConstraint info b) => Proxy o -> b -> IO (AttrTransferType info) Source #
Allocate memory as necessary to generate a settable type from the transfer type. This is useful for types which needs allocations for marshalling from Haskell to C, this makes the allocation explicit.
default attrTransfer :: forall o b. (AttrBaseTypeConstraint info o, AttrTransferTypeConstraint info b, b ~ AttrGetType info, b ~ AttrTransferType info) => Proxy o -> b -> IO (AttrTransferType info) Source #
Possible operations on an attribute.
AttrGet | It is possible to read the value of the attribute
with |
AttrSet | It is possible to write the value of the attribute
with |
AttrConstruct | It is possible to set the value of the attribute
in |
AttrClear | It is possible to clear the value of the
(nullable) attribute with |
Instances
Bounded AttrOpTag Source # | |
Enum AttrOpTag Source # | |
Defined in Data.GI.Base.Attributes succ :: AttrOpTag -> AttrOpTag # pred :: AttrOpTag -> AttrOpTag # fromEnum :: AttrOpTag -> Int # enumFrom :: AttrOpTag -> [AttrOpTag] # enumFromThen :: AttrOpTag -> AttrOpTag -> [AttrOpTag] # enumFromTo :: AttrOpTag -> AttrOpTag -> [AttrOpTag] # enumFromThenTo :: AttrOpTag -> AttrOpTag -> AttrOpTag -> [AttrOpTag] # | |
Eq AttrOpTag Source # | |
Ord AttrOpTag Source # | |
Defined in Data.GI.Base.Attributes | |
Show AttrOpTag Source # | |
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 |
(:&=) :: (HasAttributeList obj, info ~ ResolveAttribute attr obj, AttrInfo info, AttrBaseTypeConstraint info obj, AttrOpAllowed tag info obj, AttrTransferTypeConstraint info b, AttrSetTypeConstraint info (AttrTransferType info)) => AttrLabelProxy (attr :: Symbol) -> b -> AttrOp obj tag | Assign a value to an attribute, allocating any necessary
memory for representing the Haskell value as a C value. Note
that it is the responsibility of the caller to make sure that
the memory is freed when no longer used, otherwise there will
be a memory leak. In the majority of cases you probably want to
use |
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 |
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 # | |
Defined in Data.GI.Base.Attributes fromLabel :: AttrLabelProxy a # |