3 (* A simple calculator ported from LablTk to LablGtk *)
5 let mem_string ~char s =
7 for i = 0 to String.length s -1 do
8 if s.[i] = char then raise Exit
12 let ops = ['+',(+.); '-',(-.); '*',( *.); '/',(/.)]
14 (* The abstract calculator class. Does not use Gtk *)
16 class virtual calc = object (calc)
19 val mutable displaying = true
21 method virtual set : string -> unit
22 method virtual get : string
23 method virtual quit : unit -> unit
24 method insert s = calc#set (calc#get ^ s)
25 method get_float = float_of_string (calc#get)
27 initializer calc#set "0"
30 if s <> "" then match s.[0] with
32 if displaying then (calc#set ""; displaying <- false);
36 (calc#set "0."; displaying <- false)
38 if not (mem_string ~char:'.' calc#get) then calc#insert s
39 | '+'|'-'|'*'|'/' as c ->
44 op <- Some (List.assoc c ops)
46 x <- f x (calc#get_float);
47 op <- Some (List.assoc c ops);
48 calc#set (string_of_float x)
55 x <- f x (calc#get_float);
57 calc#set (string_of_float x)
63 (* Buttons for the calculator *)
66 [|[|"7";"8";"9";"+"|];
71 (* The physical calculator. Inherits from the abstract one *)
75 class calculator ?packing ?show () =
76 let table = GPack.table ~rows:5 ~columns:4 ~homogeneous:true ~show:false () in
81 let frame = GBin.frame ~shadow_type:`IN ()
82 ~packing:(table#attach ~left:0 ~top:0 ~right:4 ~expand:`BOTH) in
83 let evbox = GBin.event_box ~packing:frame#add () in
84 evbox#misc#set_style evbox#misc#style#copy;
85 evbox#misc#style#set_bg [`NORMAL,`WHITE];
86 GMisc.label ~justify:`RIGHT ~xalign:0.95 ~packing:evbox#add ()
89 method set = label#set_text
90 method get = label#text
91 method quit = Main.quit
94 for i = 0 to 3 do for j = 0 to 3 do
96 GButton.button ~label:(" " ^ m.(i).(j) ^ " ")
97 ~packing:(table#attach ~top:(i+1) ~left:j ~expand:`BOTH) () in
98 button#connect#clicked ~callback:(fun () -> calc#command m.(i).(j));
100 ignore (GObj.pack_return table ~packing ~show)
103 (* Finally start everything *)
105 let w = GWindow.window ~auto_shrink:true ()
107 let applet = new calculator ~packing: w#add ()
110 w#connect#destroy ~callback: Main.quit;
111 w#event#connect#key_press
112 ~callback:(fun ev -> applet#command (GdkEvent.Key.string ev); true);