Blame support/rawwidget.ml

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)