home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lifeos2.zip / LIFE-1.02 / LIB / XTOOLS_B.LF < prev    next >
Text File  |  1996-06-04  |  11KB  |  489 lines

  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. %    $Id: xtools_b.lf,v 1.3 1996/02/01 23:19:01 vorbeck Exp $    
  3. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4. %
  5. % XTOOLS: BOXES
  6. %
  7. % Author: Bruno Dumant
  8. % (c) Copyright 1993 - Digital Equipment Corporation 
  9. % All Rights Reserved
  10. %
  11. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  12. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  13.  
  14. %%% interface
  15.  
  16. public( l_above,c_above,r_above,             %% l: left       v: vertical
  17.     l_below,c_below,r_below,             %% r: right      b: bottom
  18.     t_left_of,c_left_of,b_left_of,       %% c: center     h: horizontal
  19.     t_right_of,c_right_of,b_right_of,    %% t: top
  20.  
  21.     ll_aligned,lr_aligned,lc_aligned,rr_aligned,rc_aligned,
  22.     tt_aligned,tb_aligned,tc_aligned,bb_aligned,bc_aligned,
  23.     cc_v_aligned,cc_h_aligned,
  24.  
  25.     containing,contains,      
  26.         
  27.     init_box,create_box,create_boxes,
  28.     box,v_box,h_box,null_box,t_box,
  29.  
  30.     widget,
  31.  
  32.     same_size,same_height,same_width,
  33.     vl_list,vc_list,vr_list,
  34.     ht_list,hc_list,hb_list,
  35.     menu_list,
  36.     array,
  37.  
  38.         move_widget
  39.        ) ?
  40.  
  41.  
  42. %%% Operators
  43.   
  44. op(500,xfy,l_above)?
  45. op(500,xfy,c_above)?
  46. op(500,xfy,r_above)?
  47. op(500,xfy,l_below)?
  48. op(500,xfy,c_below)?
  49. op(500,xfy,r_below)?
  50. op(500,xfy,t_left_of)?
  51. op(500,xfy,c_left_of)?
  52. op(500,xfy,b_left_of)?
  53. op(500,xfy,t_right_of)?
  54. op(500,xfy,c_right_of)?
  55. op(500,xfy,b_right_of)?
  56. op(600,xfy,containing)?
  57. op(650,xfx,contains)?
  58.  
  59. op(650,xfx,ll_aligned) ?
  60. op(650,xfx,lr_aligned) ?
  61. op(650,xfx,lc_aligned) ?
  62. op(650,xfx,rr_aligned) ?
  63. op(650,xfx,rc_aligned) ?
  64.  
  65. op(650,xfx,tt_aligned) ?
  66. op(650,xfx,tb_aligned) ?
  67. op(650,xfx,tc_aligned) ?
  68. op(650,xfx,bb_aligned) ?
  69. op(650,xfx,bc_aligned) ?
  70.  
  71. op(650,xfx,cc_v_aligned) ?
  72. op(650,xfx,cc_h_aligned) ?
  73.  
  74. op(350,fx,vl_list) ?
  75. op(350,fx,vc_list) ?
  76. op(350,fx,vr_list) ?
  77. op(350,fx,ht_list) ?
  78. op(350,fx,hc_list) ?
  79. op(350,fx,hb_list) ?
  80. op(350,fx,menu_list) ?
  81.  
  82. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  83. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  84. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  85.  
  86. %%% box
  87.  
  88. :: box( X,Y,DX,DY,
  89.     width => DX,height => DY,
  90.     border => B,
  91.     mother => M).
  92.  
  93.  
  94. %%% widget: a box with an associated window
  95.  
  96. :: widget(window => W,color_id => C).
  97. widget <| box.
  98.  
  99. ig(A) -> cond( A :=< widget, 0, 1).
  100.  
  101.  
  102. %%% init_box
  103.  
  104. init_box(Box:box(created => @)) :-
  105.     ( 
  106.         has_feature(id,Box),!
  107.     ;
  108.         find_size(Box),
  109.         Box.id = Id:gen_id,
  110.         Box.mother.daughters.Id = Box,
  111.         cond( Box :\=< widget,
  112.             Box.window = Box.mother.window
  113.         )
  114.     ).
  115.  
  116. %%% create_box
  117.  
  118. create_box(Box:box(created => C)) :-
  119.     ( 
  120.         C :\== true,!,
  121.             cond( has_feature(constructor,Box,P),
  122.             P
  123.         ),
  124.         cond( Box :< look,
  125.             draw_look(Box)
  126.         ),
  127.         cond( has_feature(daughters,Box,Daughters),
  128.             create_daughters(Daughters)
  129.         ),
  130.         C = true
  131.     ;
  132.         succeed
  133.     ).
  134.  
  135. create_daughters(Daughters) :-
  136.     create_daughters2(features(Daughters),Daughters).
  137.  
  138. create_daughters2([]) :- !.
  139. create_daughters2([A|B],Daughters) :-
  140.     create_box(Daughters.A),
  141.     create_daughters2(B,Daughters).
  142.  
  143. create_boxes(L) :- maprel(create_box,L).
  144.  
  145. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  146. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  147. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  148.  
  149. %%% definition of the operations on boxes
  150.  
  151. B1:box(X1,Y1,DX1,DY1,mother => M1) l_above B2:box(X2,Y2,DX2,DY2,mother => M2) 
  152.     -> box(X1,Y1,max(DX1,DX2),DY1+DY2,mother => M1,id => 0) |
  153.         M1 = M2,
  154.         X2 = X1,
  155.     Y2 = Y1 + DY1,
  156.     init_box(B1),
  157.     init_box(B2).
  158.  
  159. B1:box(X1,Y1,DX1,DY1,mother => M1) r_above B2:box(X2,Y2,DX2,DY2,mother => M2) 
  160.     ->    box(X,Y1,max(DX1,DX2),DY1+DY2,mother => M1,id => 0) |
  161.         M1 = M2,
  162.     cond( DDX:(DX2 - DX1) >= 0,
  163.         X = X2,
  164.         X = X1
  165.     ),
  166.         X1 = X2 + DDX,
  167.        Y2 = Y1 + DY1,
  168.     init_box(B1),
  169.     init_box(B2).
  170.  
  171. B1:box(X1,Y1,DX1,DY1,mother => M1) c_above B2:box(X2,Y2,DX2,DY2,mother => M2) 
  172.     ->    box(X,Y1,max(DX1,DX2),DY1+DY2,mother => M1,id => 0) |
  173.         M1 = M2,
  174.     cond( DDX:(DX2 - DX1) >= 0,
  175.         X = X2,
  176.         X = X1
  177.     ),
  178.         X1 = X2 + DDX/2,
  179.     Y2 = Y1 + DY1,
  180.     init_box(B1),
  181.     init_box(B2).
  182.  
  183. B1 l_below B2 ->
  184.     B2 l_above B1.
  185.  
  186. B1 r_below B2 ->
  187.     B2 r_above B1.
  188.  
  189. B1 c_below B2 ->
  190.     B2 c_above B1.
  191.  
  192.  
  193. B1:box(X1,Y1,DX1,DY1,mother => M1) t_left_of B2:box(X2,Y2,DX2,DY2,mother => M2)
  194.     -> box(X1,Y1,DX1 + DX2,max(DY1,DY2),mother => M1,id => 0) |
  195.         M1 = M2,
  196.         Y2 = Y1,
  197.     X2 = X1 + DX1,
  198.     init_box(B1),
  199.     init_box(B2).
  200.  
  201. B1:box(X1,Y1,DX1,DY1,mother => M1) b_left_of B2:box(X2,Y2,DX2,DY2,mother => M2)
  202.     -> box(X1,Y,DX1 + DX2,max(DY1,DY2),mother => M1,id => 0) |
  203.         M1 = M2,
  204.     cond( DDY:(DY2 - DY1) >= 0,
  205.         Y = Y2,
  206.         Y = Y1
  207.     ),
  208.         Y1 = Y2 + DDY,
  209.        X2 = X1 + DX1,
  210.     init_box(B1),
  211.     init_box(B2).
  212.  
  213. B1:box(X1,Y1,DX1,DY1,mother => M1) c_left_of B2:box(X2,Y2,DX2,DY2,mother => M2)
  214.     ->    box(X1,Y,DX1 + DX2,max(DY1,DY2),mother => M1,id => 0) |      
  215.     M1 = M2,
  216.     cond( DDY:(DY2 - DY1) >= 0,
  217.         Y = Y2,
  218.         Y = Y1
  219.     ),
  220.         Y1 = Y2 + DDY/2,
  221.     X2 = X1 + DX1,
  222.     init_box(B1),
  223.     init_box(B2).
  224.  
  225. B1 t_right_of B2 -> B2 t_left_of B1.
  226.  
  227. B1 b_right_of B2 -> B2 b_left_of B1.
  228.  
  229. B1 c_right_of B2 -> B2 c_left_of B1.
  230.  
  231.  
  232. B1:box containing B2:box  -> B1 |
  233.         B1 contains B2.
  234.  
  235. B1:box(X1,Y1,DX1,DY1,border => Border) contains B2:box(width => DX2,
  236.                                                    height => DY2) :-
  237.     Border = {num(d_border);real},!,
  238.     cond( B1 :=< widget,
  239.           B2 = @(Dx,Dy,mother => B1),
  240.           (
  241.           true |
  242.           B2 = @(X2,Y2,mother => B1.mother),
  243.           Dx = X2 - X1,
  244.           Dy = Y2 - Y1
  245.           )
  246.         ),
  247.     Dx = {Border;real},!,
  248.     Dy = {root_sort(Border);real},!, 
  249.     init_box(B2),
  250.     DX1 = {0;real},DY1 = {0;real},
  251.     DX1 <- max(Dx + DX2 + Border,DX1),
  252.     DY1 <- max(Dy + DY2 + Border,DY1),!,
  253.     init_box(B1),
  254.     !.
  255.  
  256. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  257. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  258. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  259.  
  260. %%% simple placement constraints
  261.  
  262. B1:box(X1) ll_aligned B2:box(X1) :- 
  263.     init_box(B1),
  264.     init_box(B2).
  265. B1:box(X1) lr_aligned B2:box(X2,_,DX2) :- 
  266.     X2 + DX2 = X1,
  267.     init_box(B1),
  268.     init_box(B2).
  269. B1:box(X1) lc_aligned B2:box(X2,_,DX2) :- 
  270.     X2 + DX2/2 = X1,
  271.     init_box(B1),
  272.     init_box(B2).
  273. B1:box(X1,_,DX1) rr_aligned B2:box(X2,_,DX2) :- 
  274.     X1 = X2 + DX2 - DX1,
  275.     init_box(B1),
  276.     init_box(B2).
  277. B1:box(X1,_,DX1) rc_aligned B2:box(X2,_,DX2) :-
  278.     X1 = X2 + DX2/2 - DX1,
  279.     init_box(B1),
  280.     init_box(B2).
  281. B1:box(X1,_,DX1) cc_v_aligned B2:box(X2,_,DX2) :- 
  282.     X1 = X2 + (DX2-DX1)/2,
  283.     init_box(B1),
  284.     init_box(B2).
  285.  
  286. B1:box(_,Y1) tt_aligned B2:box(_,Y1) :-
  287.     init_box(B1),init_box(B2).
  288. B1:box(_,Y1) tb_aligned B2:box(_,Y2,_,DY2) :- 
  289.     Y1 = Y2 + DY2,
  290.     init_box(B1),
  291.     init_box(B2).
  292. B1:box(_,Y1) tc_aligned B2:box(_,Y2,_,DY2) :- 
  293.     Y1 = Y2 + DY2/2,
  294.     init_box(B1),
  295.     init_box(B2).
  296. B1:box(_,Y1,_,DY1) bb_aligned B2:box(_,Y2,_,DY2) :- 
  297.     Y1 = Y2 + DY2 - DY1,
  298.     init_box(B1),
  299.     init_box(B2).
  300. B1:box(_,Y1,_,DY1) bc_aligned B2:box(_,Y2,_,DY2) :- 
  301.     Y1 = Y2 + DY2/2 - DY1,
  302.     init_box(B1),
  303.     init_box(B2).
  304. B1:box(_,Y1,_,DY1) cc_h_aligned B2:box(_,Y2,_,DY2) :- 
  305.     Y1 = Y2 + (DY2 - DY1)/2,
  306.     init_box(B1),
  307.     init_box(B2).
  308.  
  309. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  310. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  311. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  312.  
  313. %%% some special boxes
  314.  
  315. %%% t_box: a box with text
  316.  
  317. :: T:t_box(text => string,
  318.        h_space => H,
  319.        v_space => V).
  320.  
  321. t_box <| box.
  322.  
  323.  
  324. %%% v_box, h_box, null_box
  325.  
  326. v_box(N) -> box(width => 0,height => N,id => 0).
  327. h_box(N) -> box(width => N,height => 0,id => 0).
  328.  
  329. null_box <| box.
  330. :: null_box(width => 0,height => 0,id => 0).
  331.  
  332. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  333. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  334. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  335.  
  336. %%% utilities
  337.  
  338. %%% vertical and horizontal lists
  339.  
  340. vl_list([A|B]) -> A l_above vl_list(B).
  341. vl_list([]) -> null_box.
  342.  
  343. vc_list([A|B]) -> A c_above vc_list(B).
  344. vc_list([]) -> null_box.
  345.  
  346. vr_list([A|B]) -> A r_above vr_list(B).
  347. vr_list([]) -> null_box.
  348.  
  349. ht_list([A|B]) -> A t_left_of ht_list(B).
  350. ht_list([]) -> null_box.
  351.  
  352. hc_list([A|B]) -> A c_left_of hc_list(B).
  353. hc_list([]) -> null_box.
  354.  
  355. hb_list([A|B]) -> A b_left_of hb_list(B).
  356. hb_list([]) -> null_box.
  357.  
  358.  
  359. %%% arrays
  360.  
  361. array([]) -> null_box.
  362. array(L,N:int) -> Array |
  363.         (A,B) = split_list(L,N),
  364.     same_height(A),
  365.     Array = ht_list(A) l_above array(B,N).
  366.  
  367.  
  368. split_list(L,0) -> ([],L).    
  369. split_list([],N:int) -> ([],[]).
  370. split_list([H|T],N)  -> ([H|R],L) | (R,L)=split_list(T,N-1).
  371.  
  372.  
  373. %%% menu list
  374.  
  375. menu_list L -> 
  376.     B
  377.     |
  378.         same_size(L),
  379.     B = vl_list(L).
  380.  
  381.  
  382. %%% constrain boxes to the same size
  383. %%% Beware: persistent variables not allowed
  384.  
  385. same_size(L) :-
  386.     !,
  387.     same_size2(L,0,0).
  388.  
  389. same_size2([A:box(width => DX,height => DY)|B],RX,RY) :-
  390.     !,
  391.     find_size(A),
  392.     RX <- max(num(DX),RX),
  393.     RY <- max(num(DY),RY),
  394.     DX <- RX,
  395.     DY <- RY,
  396.     same_size2(B,RX,RY).
  397.     
  398. same_size2([]).
  399.  
  400. %%% constrain boxes to the same height
  401. %%% Beware: persistent variables not allowed
  402.  
  403. same_height(L) :-
  404.     !,
  405.     same_height2(L,0).
  406.  
  407. same_height2([A:box(height => DY)|B],RY) :-
  408.     !,
  409.     SY = get_size(A).2,
  410.     RY <- max(num(SY),RY),
  411.     DY <- RY,
  412.     same_height2(B,RY).
  413.     
  414. same_height2([]).
  415.  
  416. %%% constrain boxes to the same height
  417. %%% Beware: persistent variables not allowed
  418.  
  419. same_width(L) :-
  420.     !,
  421.     same_width2(L,0).
  422.  
  423. same_width2([A:box(width => DX)|B],RX) :-
  424.     !,
  425.     SX = get_size(A).1,
  426.     RX <- max(num(SX),RX),
  427.     DX <- RX,
  428.     same_width2(B,RX).
  429.     
  430. same_width2([]).
  431.  
  432.  
  433. num(X) -> root_sort(X).
  434.  
  435.  
  436. find_size(Box:box(width =>DX,height=>DY)) :-
  437.         (
  438.         Box :< t_box,!,
  439.         Box = @(text => Text,font_id => F,
  440.                 h_space => H, v_space => V,
  441.             offset => Offset),
  442.         !,
  443.         xQueryTextExtents(default_display,Font:text_font(F),Text,
  444.                           font_ascent => FA, font_descent => FD,
  445.                   text_width => W),
  446.         H = {d_h_space;real},
  447.         V = {d_v_space;real},
  448.         Offset = {d_offset; real},
  449.         !,
  450.         DX = {W + H + abs(Offset); real},
  451.         DY = {FA + FD + V;real},
  452.         !
  453.     ;
  454.         DX = {10;real},
  455.         DY = {10;real},
  456.         !
  457.     ).
  458.  
  459. get_size(Box:box(width =>DX,height=>DY)) -> (SX,SY) |
  460.         (
  461.         Box :< t_box,!,
  462.         Box = @(text => Text,font_id => F,
  463.                 h_space => H, v_space => V),
  464.         !,
  465.         xQueryTextExtents(default_display,Font:text_font(F),Text,
  466.                           font_ascent => FA, font_descent => FD,
  467.                   text_width => W),
  468.         H = {d_h_space;real},
  469.         V = {d_v_space;real},
  470.         !,
  471.         SX = {W + H;real} & num(DX),
  472.         SY = {FA + FD + V;real} & num(DY),
  473.         !
  474.     ;
  475.         SX = {10;real} & num(DX),
  476.         SY = {10;real} & num(DY),
  477.         !
  478.     ).
  479.  
  480. move_widget(Box:widget,X,Y) :-
  481.     xMoveWindow(Box.window,X,Y),
  482.         Box.1 <- num(X),
  483.     Box.2 <- num(Y).
  484.  
  485.  
  486. global(id_counter <- 1)?
  487. gen_id -> num(id_counter) | id_counter <- id_counter + 1. 
  488.  
  489.