|
Packit |
bd2e5d |
(***********************************************************************)
|
|
Packit |
bd2e5d |
(* *)
|
|
Packit |
bd2e5d |
(* MLTk, Tcl/Tk interface of OCaml *)
|
|
Packit |
bd2e5d |
(* *)
|
|
Packit |
bd2e5d |
(* Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis *)
|
|
Packit |
bd2e5d |
(* projet Cristal, INRIA Rocquencourt *)
|
|
Packit |
bd2e5d |
(* Jacques Garrigue, Kyoto University RIMS *)
|
|
Packit |
bd2e5d |
(* *)
|
|
Packit |
bd2e5d |
(* Copyright 2002 Institut National de Recherche en Informatique et *)
|
|
Packit |
bd2e5d |
(* en Automatique and Kyoto University. All rights reserved. *)
|
|
Packit |
bd2e5d |
(* This file is distributed under the terms of the GNU Library *)
|
|
Packit |
bd2e5d |
(* General Public License, with the special exception on linking *)
|
|
Packit |
bd2e5d |
(* described in file LICENSE found in the OCaml source tree. *)
|
|
Packit |
bd2e5d |
(* *)
|
|
Packit |
bd2e5d |
(***********************************************************************)
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(* $Id$ *)
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(*
|
|
Packit |
bd2e5d |
* Widgets
|
|
Packit |
bd2e5d |
*)
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
exception IllegalWidgetType of string
|
|
Packit |
bd2e5d |
(* Raised when widget command applied illegally*)
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(***************************************************)
|
|
Packit |
bd2e5d |
(* Widgets *)
|
|
Packit |
bd2e5d |
(* This 'a raw_widget will be 'a Widget.widget *)
|
|
Packit |
bd2e5d |
(***************************************************)
|
|
Packit |
bd2e5d |
type 'a raw_widget =
|
|
Packit |
bd2e5d |
Untyped of string
|
|
Packit |
bd2e5d |
| Typed of string * string
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
type raw_any (* will be Widget.any *)
|
|
Packit |
bd2e5d |
and button
|
|
Packit |
bd2e5d |
and canvas
|
|
Packit |
bd2e5d |
and checkbutton
|
|
Packit |
bd2e5d |
and entry
|
|
Packit |
bd2e5d |
and frame
|
|
Packit |
bd2e5d |
and label
|
|
Packit |
bd2e5d |
and listbox
|
|
Packit |
bd2e5d |
and menu
|
|
Packit |
bd2e5d |
and menubutton
|
|
Packit |
bd2e5d |
and message
|
|
Packit |
bd2e5d |
and radiobutton
|
|
Packit |
bd2e5d |
and scale
|
|
Packit |
bd2e5d |
and scrollbar
|
|
Packit |
bd2e5d |
and text
|
|
Packit |
bd2e5d |
and toplevel
|
|
Packit |
bd2e5d |
and ttk_labelframe
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
let forget_type w = (Obj.magic (w : 'a raw_widget) : raw_any raw_widget)
|
|
Packit |
bd2e5d |
let coe = forget_type
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(* table of widgets *)
|
|
Packit |
bd2e5d |
let table = (Hashtbl.create 401 : (string, raw_any raw_widget) Hashtbl.t)
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
let name = function
|
|
Packit |
bd2e5d |
Untyped s -> s
|
|
Packit |
bd2e5d |
| Typed (s,_) -> s
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(* Normally all widgets are known *)
|
|
Packit |
bd2e5d |
(* this is a provision for send commands to external tk processes *)
|
|
Packit |
bd2e5d |
let known_class = function
|
|
Packit |
bd2e5d |
Untyped _ -> "unknown"
|
|
Packit |
bd2e5d |
| Typed (_,c) -> c
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(* This one is always created by opentk *)
|
|
Packit |
bd2e5d |
let default_toplevel =
|
|
Packit |
bd2e5d |
let wname = "." in
|
|
Packit |
bd2e5d |
let w = Typed (wname, "toplevel") in
|
|
Packit |
bd2e5d |
Hashtbl.add table wname w;
|
|
Packit |
bd2e5d |
w
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(* Dummy widget to which global callbacks are associated *)
|
|
Packit |
bd2e5d |
(* also passed around by camltotkoption when no widget in context *)
|
|
Packit |
bd2e5d |
let dummy =
|
|
Packit |
bd2e5d |
Untyped "dummy"
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
let remove w =
|
|
Packit |
bd2e5d |
Hashtbl.remove table (name w)
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(* Retype widgets returned from Tk *)
|
|
Packit |
bd2e5d |
(* JPF report: sometime s is "", see Protocol.cTKtoCAMLwidget *)
|
|
Packit |
bd2e5d |
let get_atom s =
|
|
Packit |
bd2e5d |
try
|
|
Packit |
bd2e5d |
Hashtbl.find table s
|
|
Packit |
bd2e5d |
with
|
|
Packit |
bd2e5d |
Not_found -> Untyped s
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
let naming_scheme = [
|
|
Packit |
bd2e5d |
"button", "b";
|
|
Packit |
bd2e5d |
"canvas", "ca";
|
|
Packit |
bd2e5d |
"checkbutton", "cb";
|
|
Packit |
bd2e5d |
"entry", "en";
|
|
Packit |
bd2e5d |
"frame", "f";
|
|
Packit |
bd2e5d |
"label", "l";
|
|
Packit |
bd2e5d |
"listbox", "li";
|
|
Packit |
bd2e5d |
"menu", "me";
|
|
Packit |
bd2e5d |
"menubutton", "mb";
|
|
Packit |
bd2e5d |
"message", "ms";
|
|
Packit |
bd2e5d |
"radiobutton", "rb";
|
|
Packit |
bd2e5d |
"scale", "sc";
|
|
Packit |
bd2e5d |
"scrollbar", "sb";
|
|
Packit |
bd2e5d |
"text", "t";
|
|
Packit |
bd2e5d |
"toplevel", "top" ]
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
let widget_any_table = List.map fst naming_scheme
|
|
Packit |
bd2e5d |
(* subtypes *)
|
|
Packit |
bd2e5d |
let widget_button_table = [ "button" ]
|
|
Packit |
bd2e5d |
and widget_canvas_table = [ "canvas" ]
|
|
Packit |
bd2e5d |
and widget_checkbutton_table = [ "checkbutton" ]
|
|
Packit |
bd2e5d |
and widget_entry_table = [ "entry" ]
|
|
Packit |
bd2e5d |
and widget_frame_table = [ "frame" ]
|
|
Packit |
bd2e5d |
and widget_label_table = [ "label" ]
|
|
Packit |
bd2e5d |
and widget_listbox_table = [ "listbox" ]
|
|
Packit |
bd2e5d |
and widget_menu_table = [ "menu" ]
|
|
Packit |
bd2e5d |
and widget_menubutton_table = [ "menubutton" ]
|
|
Packit |
bd2e5d |
and widget_message_table = [ "message" ]
|
|
Packit |
bd2e5d |
and widget_radiobutton_table = [ "radiobutton" ]
|
|
Packit |
bd2e5d |
and widget_scale_table = [ "scale" ]
|
|
Packit |
bd2e5d |
and widget_scrollbar_table = [ "scrollbar" ]
|
|
Packit |
bd2e5d |
and widget_text_table = [ "text" ]
|
|
Packit |
bd2e5d |
and widget_toplevel_table = [ "toplevel" ]
|
|
Packit |
bd2e5d |
and widget_ttk_labelframe_table = [ "ttk::labelframe" ]
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
let new_suffix clas n =
|
|
Packit |
bd2e5d |
try
|
|
Packit |
bd2e5d |
(List.assoc clas naming_scheme) ^ (string_of_int n)
|
|
Packit |
bd2e5d |
with
|
|
Packit |
bd2e5d |
Not_found -> "w" ^ (string_of_int n)
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(* The function called by generic creation *)
|
|
Packit |
bd2e5d |
let counter = ref 0
|
|
Packit |
bd2e5d |
let new_atom ~parent ?name:nom clas =
|
|
Packit |
bd2e5d |
let parentpath = name parent in
|
|
Packit |
bd2e5d |
let path =
|
|
Packit |
bd2e5d |
match nom with
|
|
Packit |
bd2e5d |
None ->
|
|
Packit |
bd2e5d |
incr counter;
|
|
Packit |
bd2e5d |
if parentpath = "."
|
|
Packit |
bd2e5d |
then "." ^ (new_suffix clas !counter)
|
|
Packit |
bd2e5d |
else parentpath ^ "." ^ (new_suffix clas !counter)
|
|
Packit |
bd2e5d |
| Some name ->
|
|
Packit |
bd2e5d |
if parentpath = "."
|
|
Packit |
bd2e5d |
then "." ^ name
|
|
Packit |
bd2e5d |
else parentpath ^ "." ^ name
|
|
Packit |
bd2e5d |
in
|
|
Packit |
bd2e5d |
let w = Typed(path,clas) in
|
|
Packit |
bd2e5d |
Hashtbl.add table path w;
|
|
Packit |
bd2e5d |
w
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(* Just create a path. Only to check existence of widgets *)
|
|
Packit |
bd2e5d |
(* Use with care *)
|
|
Packit |
bd2e5d |
let atom ~parent ~name:pathcomp =
|
|
Packit |
bd2e5d |
let parentpath = name parent in
|
|
Packit |
bd2e5d |
let path =
|
|
Packit |
bd2e5d |
if parentpath = "."
|
|
Packit |
bd2e5d |
then "." ^ pathcomp
|
|
Packit |
bd2e5d |
else parentpath ^ "." ^ pathcomp in
|
|
Packit |
bd2e5d |
Untyped path
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(* LablTk: Redundant with subtyping of Widget, backward compatibility *)
|
|
Packit |
bd2e5d |
let check_class w clas =
|
|
Packit |
bd2e5d |
match w with
|
|
Packit |
bd2e5d |
Untyped _ -> () (* assume run-time check by tk*)
|
|
Packit |
bd2e5d |
| Typed(_,c) ->
|
|
Packit |
bd2e5d |
if List.mem c clas then ()
|
|
Packit |
bd2e5d |
else raise (IllegalWidgetType c)
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(* Checking membership of constructor in subtype table *)
|
|
Packit |
bd2e5d |
let chk_sub errname table c =
|
|
Packit |
bd2e5d |
if List.mem c table then ()
|
|
Packit |
bd2e5d |
else raise (Invalid_argument errname)
|