]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/DEVEL/lablgtkmathview/gMathViewAux.ml
* binding update to recognize the new event scheme generated by
[helm.git] / helm / DEVEL / lablgtkmathview / gMathViewAux.ml
index 9fe2c80a5d782ba2dfc6d95c020c7e53c3d6961d..d23ce2d1cc42f210452d5de71a0ce76f00ad9457 100644 (file)
@@ -43,6 +43,15 @@ let rec descendant_of (n1 : Gdome.node) (n2 : Gdome.node) =
      None -> false
    | Some n1' -> descendant_of n1' n2
 
+let remove_descendants_of (el : Gdome.element) =
+ let rec aux =
+  function
+     [] -> []
+   | hd::tl when descendant_of (hd :> Gdome.node) (el :> Gdome.node) -> aux tl
+   | hd::tl -> hd::(aux tl)
+ in
+  aux
+
 (* mem el l = true if the node n is stored in the list l *)
 let mem (el : Gdome.element) =
  let rec mem_aux =
@@ -74,36 +83,85 @@ class single_selection_math_view_signals obj (set_selection_changed : (Gdome.ele
 class single_selection_math_view obj =
   object(self)
    inherit GMathView.math_view_skel obj
-   val mutable root_selection = None
+   val mutable first_selected = None
+   val mutable root_selected = None
    val mutable selection_changed = (fun _ -> ())
 
-   method set_selection root_selection' =
+   method set_selection elem =
     begin
-     match root_selection with
+     match root_selected with
         None -> ()
       | Some e -> self#unselect e
     end;
-    root_selection <- root_selection';
-    match root_selection' with
+    root_selected <- elem;
+    match elem with
        None -> ()
      | Some e -> self#select e
 
-   method get_selection = root_selection
+   method get_selection = root_selected
 
    method connect =
     new single_selection_math_view_signals obj (function f -> selection_changed <- f)
 
+   method action_toggle (elem : Gdome.element) =
+    match elem#get_namespaceURI, elem#get_localName with
+       Some ns, Some ln when ns#to_string = "http://www.w3.org/1998/Math/MathML" &&
+                             ln#to_string = "maction" ->
+        begin
+         let selection_attr = Gdome.domString "selection" in
+         let selection =
+          if elem#hasAttribute ~name:selection_attr then
+           int_of_string (elem#getAttribute ~name:selection_attr)#to_string
+          else
+           1
+         in
+          self#freeze ;
+          (* the widget will cast the index back into a valid range *)
+          elem#setAttribute ~name:selection_attr ~value:(Gdome.domString (string_of_int (selection + 1))) ;
+          self#thaw ;
+          true
+       end
+     | _ ->
+        begin
+         match elem#get_parentNode with
+            Some p ->
+             begin
+              try
+               self#action_toggle (new Gdome.element_of_node p)
+              with
+               GdomeInit.DOMCastException _ -> false
+             end
+          | None -> assert false (* every element has a parent *)
+       end
+     
    initializer
     ignore
-     (self#connect#press_move
-       (fun (first: Gdome.element option) (last: Gdome.element option) ->
-         match first, last with
+     (self#connect#select_begin
+       (fun (elem : Gdome.element option) _ ->
+         if not (elem = root_selected) then selection_changed elem ;
+        first_selected <- elem)) ;
+
+    ignore
+     (self#connect#select_over
+       (fun (elem : Gdome.element option) _ ->
+         match first_selected, elem with
             None, _
           | _, None -> selection_changed None
           | Some first', Some last' ->
              selection_changed
              (Some (new Gdome.element_of_node (common_ancestor (first' :> Gdome.node) (last' :> Gdome.node)))))) ;
-    ignore (self#connect#clicked (fun _ -> self#set_selection None))
+            
+    ignore
+     (self#connect#select_end
+       (fun (elem : Gdome.element option) _ -> first_selected <- None)) ;
+
+    ignore
+     (self#connect#select_abort
+       (fun () ->
+         first_selected <- None ;
+        selection_changed None)) ;
+
+   ignore (self#connect#click (fun _ _ -> self#set_selection None))
   end
 ;;
 
@@ -149,27 +207,62 @@ class multi_selection_math_view obj =
 
    method remove_selections =
     List.iter (fun e -> self#unselect e) selected ;
-    selected <- []
+    selected <- [] ;
+    match self#get_selection with
+       None -> ()
+     | Some e -> self#select e
 
    method add_selection (elem : Gdome.element) =
-    if not (mem elem selected) then
-     selected <- elem::selected ;
-     self#select elem
+    selected <- elem::(remove_descendants_of elem selected) ;
+    self#select elem
 
    method get_selections = selected
 
-   method set_selection root_selection' =
+   method set_selection elem =
     begin
-     match root_selection with
+     match root_selected with
         None -> ()
       | Some e -> self#unselect e ; List.iter (fun e -> self#select e) selected
     end;
-    root_selection <- root_selection';
-    match root_selection' with
+    root_selected <- elem;
+    match elem with
        None -> ()
      | Some e -> self#select e
-  end
-;;
+
+   initializer
+    ignore
+     (self#connect#select_begin
+       (fun _ state ->
+         if not (List.mem `CONTROL (Gdk.Convert.modifier state)) then self#remove_selections)) ;
+
+    ignore
+     (self#connect#select_over
+       (fun _ state ->
+         Printf.printf "stable selections: %d\n" (List.length selected) ;
+         Printf.printf "select_over with state: " ;
+        let c = 
+         function
+            `SHIFT -> "shift "
+          | `LOCK -> "lock "
+          | `CONTROL -> "control "
+          | `MOD1 -> "mod1 "
+          | _ -> ""
+        in
+         List.iter (fun x -> print_string (c x)) (Gdk.Convert.modifier state) ;
+         print_char '\n' ;
+         flush stdout)) ;
+
+    ignore
+     (self#connect#select_end
+       (fun _ state ->
+         Printf.printf "select_end\n" ; flush stdout ;
+         if not (List.mem `CONTROL (Gdk.Convert.modifier state)) then self#remove_selections ;
+        match root_selected with
+           None -> ()
+         | Some e -> self#set_selection None ; self#add_selection e))
+
+   end
+ ;;
 
 let multi_selection_math_view ?adjustmenth ?adjustmentv ?font_size ?font_manager ?border_width
  ?width ?height ?packing ?show () =