(***********************************************************************) (* *) (* MLTk, Tcl/Tk interface of OCaml *) (* *) (* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *) (* projet Cristal, INRIA Rocquencourt *) (* Jacques Garrigue, Kyoto University RIMS *) (* *) (* Copyright 2002 Institut National de Recherche en Informatique et *) (* en Automatique and Kyoto University. All rights reserved. *) (* This file is distributed under the terms of the GNU Library *) (* General Public License, with the special exception on linking *) (* described in file LICENSE found in the OCaml source tree. *) (* *) (***********************************************************************) open Camltk open Protocol let rec mapi f n l = match l with [] -> [] | x::l -> let v = f n x in v::(mapi f (succ n) l) (* Same as tk_dialog, but not sharing the tkwait variable *) (* w IS the parent widget *) let f w name title mesg bitmap def buttons = let t = Toplevel.create_named w name [Class "Dialog"] in Wm.title_set t title; Wm.iconname_set t "Dialog"; Wm.protocol_set t "WM_DELETE_WINDOW" (function () -> ()); (* Wm.transient_set t (Winfo.toplevel w); *) let ftop = Frame.create_named t "top" [Relief Raised; BorderWidth (Pixels 1)] and fbot = Frame.create_named t "bot" [Relief Raised; BorderWidth (Pixels 1)] in pack [ftop][Side Side_Top; Fill Fill_Both]; pack [fbot][Side Side_Bottom; Fill Fill_Both]; let l = Label.create_named ftop "msg" [Justify Justify_Left; Text mesg; WrapLength (Pixels 600)] in pack [l][Side Side_Right; Expand true; Fill Fill_Both; PadX (Millimeters 3.0); PadY (Millimeters 3.0)]; begin match bitmap with Predefined "" -> () | _ -> let b = Label.create_named ftop "bitmap" [Bitmap bitmap] in pack [b][Side Side_Left; PadX (Millimeters 3.0); PadY (Millimeters 3.0)] end; let waitv = Textvariable.create_temporary t in let buttons = mapi (fun i bname -> let b = Button.create t [Text bname; Command (fun () -> Textvariable.set waitv (string_of_int i))] in if i = def then begin let f = Frame.create_named fbot "default" [Relief Sunken; BorderWidth (Pixels 1)] in raise_window_above b f; pack [f][Side Side_Left; Expand true; PadX (Millimeters 3.0); PadY (Millimeters 2.0)]; pack [b][In f; PadX (Millimeters 2.0); PadY (Millimeters 2.0)]; bind t [[], KeyPressDetail "Return"] (BindSet ([], (fun _ -> Button.flash b; Button.invoke b))) end else pack [b][In fbot; Side Side_Left; Expand true; PadX (Millimeters 3.0); PadY (Millimeters 2.0)]; b ) 0 buttons in Wm.withdraw t; update_idletasks(); let x = (Winfo.screenwidth t)/2 - (Winfo.reqwidth t)/2 - (Winfo.vrootx (Winfo.parent t)) and y = (Winfo.screenheight t)/2 - (Winfo.reqheight t)/2 - (Winfo.vrooty (Winfo.parent t)) in Wm.geometry_set t (Printf.sprintf "+%d+%d" x y); Wm.deiconify t; let oldfocus = try Some (Focus.get()) with _ -> None and oldgrab = Grab.current ~displayof: t () and grabstatus = ref None in begin match oldgrab with [] -> () | x::l -> grabstatus := Some(Grab.status x) end; (* avoid errors here because it makes the entire app useless *) (try Grab.set t with TkError _ -> ()); Tkwait.visibility t; Focus.set (if def >= 0 then List.nth buttons def else t); Tkwait.variable waitv; begin match oldfocus with None -> () | Some w -> try Focus.set w with _ -> () end; destroy t; begin match oldgrab with [] -> () | x::l -> try match !grabstatus with Some(GrabGlobal) -> Grab.set_global x | _ -> Grab.set x with TkError _ -> () end; int_of_string (Textvariable.get waitv)