summaryrefslogtreecommitdiff
path: root/src/Gtk/State.dcl
blob: 1dde9d193e222932c09d260f39e98d9340533097 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
definition module Gtk.State

/**
 * This module provides types and functions to set up the monadic state of a
 * Gtk program and run an application.
 */

from StdMaybe import :: Maybe

from Control.Applicative import class pure, class <*>, class Applicative
from Control.Monad import class Monad
from Data.Functor import class Functor
from Data.Map import :: Map

from Gtk.Shares import :: ShareId
from Gtk.Signal import :: SignalHandlerInternal

/**
 * In the internal state of the `GtkM` monad. It is exported for use in other
 * modules of the Gtk library; it should not normally be used by applications.
 */
:: GtkState =
	{ world           :: !()
	, return          :: !Bool
	, signal_handlers :: !Map Int SignalHandlerInternal
	, signal_counter  :: !Int
	, timeouts        :: !Map Int (GtkM Bool)
	, timeout_counter :: !Int
	, shares          :: !Map ShareId Dynamic
	}

//* The Gtk state monad.
:: GtkM a =: GtkM (GtkState -> (a, GtkState))

instance Functor GtkM
instance pure GtkM
instance <*> GtkM
instance Monad GtkM

//* A new, empty state.
newGtkState :: GtkState

//* Run a Gtk monad in a new, empty state.
runGtk :: !(GtkM a) !*World -> (!a, !*World)

//* Get the internal state.
getState :: GtkM GtkState
//* Modify the internal state.
modState :: !(GtkState -> GtkState) -> GtkM GtkState

/**
 * Run a function in the `GtkM` monad and discard its result. This function is
 * typically used with functions from `Gtk.Internal` and is not normally used
 * directly.
 */
toState :: !(A.a: a -> a) -> GtkM ()

/**
 * Run a function in the `GtkM` monad and return its result. This function is
 * typically used with functions from `Gtk.Internal` and is not normally used
 * directly.
 */
toStateR :: !(A.a: a -> (r,a)) -> GtkM r

//* Apply a function with side effects in the `GtkM` monad.
appWorld :: !(*World -> *World) -> GtkM ()
//* Apply a function with side effects in the `GtkM` monad; return its result.
accWorld :: !(*World -> (r,*World)) -> GtkM r

/**
 * Request graceful termination of the program. This sets the `return` field
 * of the `GtkState`, after which `runGtk` will terminate before the next
 * iteration.
 */
quit :: GtkM ()

/**
 * Run the Glib main loop as long as there are events pending. This may be
 * useful before starting a long blocking operation in Clean, such that all
 * updates to the views have been applied. You can thus set text in a status
 * bar or show a spinner before the blocking operation starts.
 *
 * Unfortunately, threading or Glib's background task mechanism is not
 * implemented, so the blocking operation will still freeze the GUI.
 */
runWhileEventsPending :: GtkM ()