]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/lablgtk/lablgtk_20000829-0.1.0/gUtil.ml
Initial revision
[helm.git] / helm / DEVEL / lablgtk / lablgtk_20000829-0.1.0 / gUtil.ml
1 (* $Id$ *)
2
3 open GObj
4
5 class ['a] memo () = object
6   constraint 'a = #widget
7   val tbl = Hashtbl.create 7
8   method add (obj : 'a) =
9     Hashtbl.add tbl ~key:obj#get_id ~data:obj
10   method find (obj : widget) = Hashtbl.find tbl obj#get_id
11   method remove (obj : widget) = Hashtbl.remove tbl obj#get_id
12 end
13
14 let signal_id = ref 0
15
16 let next_callback_id () : GtkSignal.id =
17   decr signal_id; Obj.magic (!signal_id : int)
18
19 class ['a] signal () = object (self)
20   val mutable callbacks : (GtkSignal.id * ('a -> unit)) list = []
21   method callbacks = callbacks
22   method connect ~after ~callback =
23     let id = next_callback_id () in
24     callbacks <-
25       if after then callbacks @ [id,callback] else (id,callback)::callbacks;
26     id
27   method call arg =
28     List.exists callbacks ~f:
29       begin fun (_,f) ->
30         let old = GtkSignal.push_callback () in
31         try f arg; GtkSignal.pop_callback old
32         with exn -> GtkSignal.pop_callback old; raise exn
33       end;
34     ()
35   method disconnect key =
36     List.mem_assoc key callbacks &&
37     (callbacks <- List.remove_assoc key callbacks; true)
38 end
39
40 class virtual ml_signals disconnectors =
41   object (self)
42     val after = false
43     method after = {< after = true >}
44     val mutable disconnectors : (GtkSignal.id -> bool) list = disconnectors
45     method disconnect key =
46       ignore (List.exists disconnectors ~f:(fun f -> f key))
47   end
48
49 class virtual add_ml_signals obj disconnectors =
50   object (self)
51     val mutable disconnectors : (GtkSignal.id -> bool) list = disconnectors
52     method disconnect key =
53       if List.exists disconnectors ~f:(fun f -> f key) then ()
54       else GtkSignal.disconnect obj key
55   end
56
57 class ['a] variable_signals ~(set : 'a signal) ~(changed : 'a signal) =
58   object
59     inherit ml_signals [changed#disconnect; set#disconnect]
60     method changed = changed#connect ~after
61     method set = set#connect ~after
62   end
63
64 class ['a] variable x =
65   object (self)
66     val changed = new signal ()
67     val set = new signal ()
68     method connect = new variable_signals ~set ~changed
69     val mutable x : 'a = x
70     method get = x
71     method set = set#call
72     method private equal : 'a -> 'a -> bool = (=)
73     method private real_set y =
74       let x0 = x in x <- y;
75       if changed#callbacks <> [] && not (self#equal x x0)
76       then changed#call y
77     initializer
78       ignore (set#connect ~after:false ~callback:self#real_set)
79   end
80