File: gladecalc.ml

package info (click to toggle)
lablgtk3 3.1.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,796 kB
  • sloc: ml: 40,890; ansic: 22,312; makefile: 133; sh: 17
file content (79 lines) | stat: -rw-r--r-- 2,546 bytes parent folder | download | duplicates (3)
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
(**************************************************************************)
(*    Lablgtk - Examples                                                  *)
(*                                                                        *)
(*    This code is in the public domain.                                  *)
(*    You may freely copy parts of it in your application.                *)
(*                                                                        *)
(**************************************************************************)

(* $Id$ *)

open StdLabels

(* lablgladecc3 project2.ui > project2.ml *)
(* #use "project2.ml";; *)
open Project2

let w1 = new window1 ()

let numbers =
  [| w1#button0; w1#button1; w1#button2; w1#button3; w1#button4;
     w1#button5; w1#button6; w1#button7; w1#button8; w1#button9 |]

let label = w1#label1

type state = Input | Result
let state = ref Result
let pending = ref (fun x -> x)

let insert_digit n =
  let prev = if !state = Result then "" else label#text in
  label#set_text (prev ^ string_of_int n);
  state := Input

let get_float () = float_of_string label#text

let insert_dot () =
  let prev = label#text in
  if not (String.contains prev '.') then label#set_text (prev ^ ".")

let set_pending f =
  pending := f (get_float ()); state := Result

let equals () =
  if !state = Input then
    label#set_text (string_of_float (!pending (get_float())));
  state := Result

let _ =
  w1#toplevel#connect#destroy ~callback:GMain.quit;
  for i = 0 to 9 do
    numbers.(i)#connect#clicked ~callback:(fun () -> insert_digit i)
  done;
  w1#button_dot#connect#clicked ~callback:insert_dot;
  List.iter ~f:
    begin fun (b, f) ->
      ignore (b#connect#clicked ~callback:(fun () -> set_pending f))
    end
    [ w1#button_add, (+.); w1#button_sub, (-.); w1#button_mul, ( *. );
      w1#button_div, (fun x y -> if y = 0. then 0. else x/.y) ];
  w1#button_eq#connect#clicked ~callback:equals;
  w1#window1#event#connect#key_press ~callback:
    begin fun ev ->
      let key = GdkEvent.Key.string ev in
      if String.length key <> 1 then false else begin
        begin match key.[0] with
        | '0'..'9' -> insert_digit (int_of_string key)
        | '.' -> insert_dot ()
        | '+' -> set_pending (+.)
        | '-' -> set_pending (-.)
        | '*' -> set_pending ( *. )
        | '/' -> set_pending (fun x y -> if y = 0. then 0. else x/.y)
        | '=' -> equals ()
        | 'q' -> GMain.Main.quit ()
        | _ -> ()
        end;
        true
      end
    end;
  GMain.Main.main ()