File: tmkPacking.ml

package info (click to toggle)
ocaml-curses 1.0.2-2
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 328 kB
  • ctags: 869
  • sloc: ml: 2,832; ansic: 673; makefile: 140; sh: 10
file content (123 lines) | stat: -rw-r--r-- 3,130 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
open TmkStruct

type 'a box_element = {
  mutable base: int;
  mutable expand: int;
  element: 'a
}

let compute_position t l =
  let (bt, et) = List.fold_left
    (fun (x,y) e -> (x + e.base, y + e.expand)) (0,0) l in
  if bt > t then failwith "too small allocation";
  let et = if et = 0 then 1 else et in
  let ep = t - bt in
  let rec aux xb xe a = function
    | [] -> []
    | h::t ->
	let a = a + h.expand in
	let nxe = a * ep / et in
	((xb + xe, h.base + nxe - xe) ::
	   (aux (xb + h.base) nxe a t)) in
  aux 0 0 0 l


let real_class_box = Class.create "Box" [TmkContainer.real_class_container]

class virtual box parent = object (self)
  inherit TmkContainer.container as super

  val mutable children = []
  val terminal = parent#terminal

  method parent = parent
  method terminal = terminal
  method children () =
    let rec aux = function
      | [] -> []
      | { element = None } :: t -> aux t
      | { element = Some e } :: t -> e :: (aux t) in
    aux children

  method add w =
    children <- children @ [{ base = 0; expand = 0; element = Some w }];
    self#signal_add_descendant#emit w

  method remove w =
    super#remove w;
    let rec aux a = function
      | ({ element = Some c} as h)::t when c == w -> (List.rev a) @ t
      | h::t -> aux (h::a) t
      | [] -> raise Not_found in
    children <- aux [] children

  method add_glue b e =
    children <- children @ [{ base = b; expand = e; element = None }]

  method set_child_expand w e =
    let aux = function
      | { element = Some x } -> x == w
      | _ -> false in
    let c = List.find aux children in
    c.expand <- e

  initializer
    parent#add self#coerce
end

let real_class_vbox = Class.create "VBox" [real_class_box]

class vbox parent = object (self)
  inherit box parent as super

  method real_class = real_class_vbox

  method class_get_size t =
    let aux (cw,ch) e =
      match e.element with
	| Some w ->
	    let (ew,eh) = w#signal_get_size#emit (0,0) in
	    e.base <- eh;
	    (max cw ew, ch + eh)
	| None ->
	    (cw, ch + e.base) in
    List.fold_left aux t children

  method class_set_geometry ((gx,gy,gw,gh) as g) =
    super#class_set_geometry g;
    let ta = compute_position gh children in
    let aux (y,h) = function
      | { element = None } -> ()
      | { element = Some w } ->
	  w#signal_set_geometry#emit (gx, gy + y, gw, h) in
    List.iter2 aux ta children
end


let real_class_hbox = Class.create "Box" [real_class_box]

class hbox parent = object (self)
  inherit box parent as super

  method real_class = real_class_hbox

  method class_get_size t =
    let aux (cw,ch) e =
      match e.element with
	| Some w ->
	    let (ew,eh) = w#signal_get_size#emit (0,0) in
	    e.base <- ew;
	    (cw + ew, max ch eh)
	| None ->
	    (cw + e.base, ch) in
    List.fold_left aux t children

  method class_set_geometry ((gx,gy,gw,gh) as g) =
    super#class_set_geometry g;
    let ta = compute_position gw children in
    let aux (x,l) = function
      | { element = None } -> ()
      | { element = Some w } ->
	  w#signal_set_geometry#emit (gx + x, gy, l, gh) in
    List.iter2 aux ta children
end