|
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 |
open Camltk
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
let version = "$Id$"
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(*
|
|
Packit |
bd2e5d |
* Link a scrollbar and a listbox
|
|
Packit |
bd2e5d |
*)
|
|
Packit |
bd2e5d |
let scroll_link sb lb =
|
|
Packit |
bd2e5d |
Listbox.configure lb
|
|
Packit |
bd2e5d |
[YScrollCommand (Scrollbar.set sb)];
|
|
Packit |
bd2e5d |
Scrollbar.configure sb
|
|
Packit |
bd2e5d |
[ScrollCommand (Listbox.yview lb)]
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
(*
|
|
Packit |
bd2e5d |
* Completion for listboxes, Macintosh style.
|
|
Packit |
bd2e5d |
* As long as you type fast enough, the listbox is repositioned to the
|
|
Packit |
bd2e5d |
* first entry "greater" than the typed prefix.
|
|
Packit |
bd2e5d |
* assumes:
|
|
Packit |
bd2e5d |
* sorted list (otherwise it's stupid)
|
|
Packit |
bd2e5d |
* fixed size, because we don't recompute size at each callback invocation
|
|
Packit |
bd2e5d |
*)
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
let add_completion lb action =
|
|
Packit |
bd2e5d |
let prefx = ref "" (* current match prefix *)
|
|
Packit |
bd2e5d |
and maxi = Listbox.size lb - 1 (* maximum index (doesn't matter actually) *)
|
|
Packit |
bd2e5d |
and current = ref 0 (* current position *)
|
|
Packit |
bd2e5d |
and lastevent = ref 0 in
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
let rec move_forward () =
|
|
Packit |
bd2e5d |
if Listbox.get lb (Number !current) < !prefx then
|
|
Packit |
bd2e5d |
if !current < maxi then begin incr current; move_forward() end
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
and recenter () =
|
|
Packit |
bd2e5d |
let element = Number !current in
|
|
Packit |
bd2e5d |
(* Clean the selection *)
|
|
Packit |
bd2e5d |
Listbox.selection_clear lb (Number 0) End;
|
|
Packit |
bd2e5d |
(* Set it to our unique element *)
|
|
Packit |
bd2e5d |
Listbox.selection_set lb element element;
|
|
Packit |
bd2e5d |
(* Activate it, to keep consistent with Up/Down.
|
|
Packit |
bd2e5d |
You have to be in Extended or Browse mode *)
|
|
Packit |
bd2e5d |
Listbox.activate lb element;
|
|
Packit |
bd2e5d |
Listbox.selection_anchor lb element;
|
|
Packit |
bd2e5d |
Listbox.see lb element in
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
let complete time s =
|
|
Packit |
bd2e5d |
if time - !lastevent < 500 then (* sorry, hard coded limit *)
|
|
Packit |
bd2e5d |
prefx := !prefx ^ s
|
|
Packit |
bd2e5d |
else begin (* reset *)
|
|
Packit |
bd2e5d |
current := 0;
|
|
Packit |
bd2e5d |
prefx := s
|
|
Packit |
bd2e5d |
end;
|
|
Packit |
bd2e5d |
lastevent := time;
|
|
Packit |
bd2e5d |
move_forward();
|
|
Packit |
bd2e5d |
recenter() in
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
bind lb [[], KeyPress]
|
|
Packit |
bd2e5d |
(BindSet([Ev_Char; Ev_Time],
|
|
Packit |
bd2e5d |
(function ev ->
|
|
Packit |
bd2e5d |
(* consider only keys producing characters. The callback is called
|
|
Packit |
bd2e5d |
* even if you press Shift.
|
|
Packit |
bd2e5d |
*)
|
|
Packit |
bd2e5d |
if ev.ev_Char <> "" then complete ev.ev_Time ev.ev_Char)));
|
|
Packit |
bd2e5d |
(* Key specific bindings override KeyPress *)
|
|
Packit |
bd2e5d |
bind lb [[], KeyPressDetail "Return"] (BindSet([], action));
|
|
Packit |
bd2e5d |
(* Finally, we have to set focus, otherwise events dont get through *)
|
|
Packit |
bd2e5d |
Focus.set lb;
|
|
Packit |
bd2e5d |
recenter() (* so that first item is selected *)
|
|
Packit |
bd2e5d |
|
|
Packit |
bd2e5d |
let new_scrollable_listbox top options =
|
|
Packit |
bd2e5d |
let f = Frame.create top [] in
|
|
Packit |
bd2e5d |
let lb = Listbox.create f options
|
|
Packit |
bd2e5d |
and sb = Scrollbar.create f [] in
|
|
Packit |
bd2e5d |
scroll_link sb lb;
|
|
Packit |
bd2e5d |
pack [lb] [Side Side_Left; Fill Fill_Both; Expand true];
|
|
Packit |
bd2e5d |
pack [sb] [Side Side_Left; Fill Fill_Y];
|
|
Packit |
bd2e5d |
f, lb
|