1 (***********************************************************************)
3 (* MLTk, Tcl/Tk interface of Objective Caml *)
5 (* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
6 (* projet Cristal, INRIA Rocquencourt *)
7 (* Jacques Garrigue, Kyoto University RIMS *)
9 (* Copyright 2002 Institut National de Recherche en Informatique et *)
10 (* en Automatique and Kyoto University. All rights reserved. *)
11 (* This file is distributed under the terms of the GNU Library *)
12 (* General Public License, with the special exception on linking *)
13 (* described in file LICENSE found in the Objective Caml source tree. *)
15 (***********************************************************************)
17 (* $Id: clock.ml 4745 2002-04-26 12:16:26Z furuse $ *)
19 (* Clock/V, a simple clock.
20 Reverts every time you push the right button.
21 Adapted from ASCII/V May 1997
23 Uses Tk and Unix, so you must link with
24 labltklink unix.cma clock.ml -o clock -cclib -lunix
29 (* pi is not a constant! *)
33 * create it with a parent: [new clock parent:top]
34 * initialize with [#init]
37 class clock ~parent = object (self)
39 (* Instance variables *)
40 val canvas = Canvas.create ~width:100 ~height:100 parent
41 val mutable height = 100
42 val mutable width = 100
43 val mutable rflag = -1
45 (* Convert from -1.0 .. 1.0 to actual positions on the canvas *)
46 method x x0 = truncate (float width *. (x0 +. 1.) /. 2.)
47 method y y0 = truncate (float height *. (y0 +. 1.) /. 2.)
50 (* Create the oval border *)
51 Canvas.create_oval canvas ~tags:["cadran"]
52 ~x1:1 ~y1:1 ~x2:(width - 2) ~y2:(height - 2)
53 ~width:3 ~outline:`Yellow ~fill:`White;
54 (* Draw the figures *)
56 (* Create the arrows with dummy position *)
57 Canvas.create_line canvas
58 ~xys:[self#x 0., self#y 0.; self#x 0., self#y 0.]
59 ~tags:["hours"] ~fill:`Red;
60 Canvas.create_line canvas
61 ~xys:[self#x 0., self#y 0.; self#x 0., self#y 0.]
62 ~tags:["minutes"] ~fill:`Blue;
63 Canvas.create_line canvas
64 ~xys:[self#x 0., self#y 0.; self#x 0., self#y 0.]
65 ~tags:["seconds"] ~fill:`Black;
66 (* Setup a timer every second *)
68 self#draw_arrows (Unix.localtime (Unix.time ()));
69 Timer.add ~ms:1000 ~callback:timer; ()
71 (* Redraw when configured (changes size) *)
72 bind canvas ~events:[`Configure] ~action:
74 width <- Winfo.width canvas;
75 height <- Winfo.height canvas;
78 (* Change direction with right button *)
79 bind canvas ~events:[`ButtonPressDetail 3]
80 ~action:(fun _ -> rflag <- -rflag; self#redraw);
81 (* Pack, expanding in both directions *)
82 pack ~fill:`Both ~expand:true [canvas]
84 (* Redraw everything *)
86 Canvas.coords_set canvas (`Tag "cadran")
87 ~xys:[ 1, 1; width - 2, height - 2 ];
89 self#draw_arrows (Unix.localtime (Unix.time ()))
91 (* Delete and redraw the figures *)
93 Canvas.delete canvas [`Tag "figures"];
95 let angle = float (rflag * i - 3) *. pi /. 6. in
96 Canvas.create_text canvas
97 ~x:(self#x (0.8 *. cos angle)) ~y:(self#y (0.8 *. sin angle))
99 ~text:(string_of_int i) ~font:"variable"
103 (* Resize and reposition the arrows *)
104 method draw_arrows tm =
105 Canvas.configure_line ~width:(min width height / 40)
106 canvas (`Tag "hours");
108 float (rflag * (tm.Unix.tm_hour * 60 + tm.Unix.tm_min) - 180)
110 Canvas.coords_set canvas (`Tag "hours")
111 ~xys:[ self#x 0., self#y 0.;
112 self#x (cos hangle /. 2.), self#y (sin hangle /. 2.) ];
113 Canvas.configure_line ~width:(min width height / 50)
114 canvas (`Tag "minutes");
115 let mangle = float (rflag * tm.Unix.tm_min - 15) *. pi /. 30. in
116 Canvas.coords_set canvas (`Tag "minutes")
117 ~xys:[ self#x 0., self#y 0.;
118 self#x (cos mangle /. 1.5), self#y (sin mangle /. 1.5) ];
119 let sangle = float (rflag * tm.Unix.tm_sec - 15) *. pi /. 30. in
120 Canvas.coords_set canvas (`Tag "seconds")
121 ~xys:[ self#x 0., self#y 0.;
122 self#x (cos sangle /. 1.25), self#y (sin sangle /. 1.25) ]
125 (* Initialize the Tcl interpreter *)
128 (* Create a clock on the main window *)
130 new clock ~parent:top
132 (* Wait for events *)