Commit 284bceeaea890489994858d9959f5ea2e30596f7

Authored by Olivier Duvernois
1 parent b9b511f5

*** empty log message ***

anubis_dev/library/widgets3/box.anubis
... ... @@ -12,8 +12,8 @@
12 12 Olivier Duvernois
13 13  
14 14  
15   -read widgets3/widget.anubis
16   -read widgets3/tools.anubis
  15 +read widget.anubis
  16 +read tools.anubis
17 17  
18 18  
19 19 This file defines the 'box' widget. A box is just a frame (shown with some relief)
... ...
anubis_dev/library/widgets3/bubble.anubis
... ... @@ -13,7 +13,7 @@
13 13  
14 14  
15 15  
16   -read widgets3/widget.anubis
  16 +read widget.anubis
17 17  
18 18  
19 19 This is the 'bubble manager' widget. This widget has a 'content' widget and is able to
... ... @@ -125,7 +125,7 @@ define One
125 125 *** Redrawing the bubble (and the content of the bubble manager).
126 126  
127 127 read tools/basis.anubis
128   -read widgets3/tools.anubis
  128 +read tools.anubis
129 129  
130 130 define One
131 131 redraw_bubble
... ...
anubis_dev/library/widgets3/button.anubis
... ... @@ -14,8 +14,8 @@
14 14  
15 15  
16 16  
17   -read widgets3/widget.anubis
18   -read widgets3/tools.anubis
  17 +read widget.anubis
  18 +read tools.anubis
19 19  
20 20  
21 21 In this file the 'button' widget is defined. The role of a button is to perform an
... ...
anubis_dev/library/widgets3/check_box.anubis
... ... @@ -5,7 +5,7 @@
5 5  
6 6  
7 7 read tools/basis.anubis
8   -read widgets3/widget.anubis
  8 +read widget.anubis
9 9  
10 10  
11 11 public define Widget
... ...
anubis_dev/library/widgets3/colors.anubis
... ... @@ -2,15 +2,12 @@
2 2  
3 3  
4 4  
5   -read widgets3/widget.anubis
6   -read widgets3/tools.anubis
7   -read widgets3/host_window.anubis
8   -read widgets3/text.anubis
9   -read widgets3/table.anubis
10   - read o_scrollbar.anubis
11   - read o_window.anubis
12   -read widgets3/space.anubis
13   - read o_geometry.anubis
  5 +read widget.anubis
  6 +read tools.anubis
  7 +read host_window.anubis
  8 +read text.anubis
  9 +read table.anubis
  10 +read space.anubis
14 11 read system_colors/rgb.anubis
15 12 read system_colors/system_colors.anubis
16 13  
... ...
anubis_dev/library/widgets3/desktop.anubis
... ... @@ -12,7 +12,7 @@
12 12 Olivier Duvernois
13 13  
14 14  
15   -read widgets3/widget.anubis
  15 +read widget.anubis
16 16  
17 17  
18 18 This is the 'desktop' widget. A 'desktop' is just a rectangular area on top of which
... ... @@ -81,7 +81,7 @@ public define Widget
81 81  
82 82  
83 83  
84   -read widgets3/tools.anubis
  84 +read tools.anubis
85 85  
86 86  
87 87 *** (1) Setting positions of childs in a desktop.
... ...
anubis_dev/library/widgets3/host_window.anubis
... ... @@ -12,7 +12,8 @@
12 12 Authors: Alain Proutรฉ
13 13  
14 14  
15   -read widgets3/widget.anubis
  15 + read widgets3/widget.anubis
  16 +read widget.anubis
16 17  
17 18  
18 19 *** (1) Opening a host window containing a widget.
... ... @@ -76,7 +77,8 @@ public define Bool
76 77 is mapped to the host window.
77 78  
78 79  
79   -read widgets3/tools.anubis
  80 + read widgets3/tools.anubis
  81 +read tools.anubis
80 82  
81 83 define (HostWindow,Rectangle) -> One
82 84 widget_paint_method
... ...
anubis_dev/library/widgets3/hypertext.anubis
... ... @@ -14,8 +14,8 @@
14 14  
15 15  
16 16  
17   -read widgets3/widget.anubis
18   -read widgets3/tools.anubis
  17 +read widget.anubis
  18 +read tools.anubis
19 19  
20 20 read tools/basis.anubis
21 21 read image.anubis
... ...
anubis_dev/library/widgets3/image.anubis
... ... @@ -18,7 +18,8 @@
18 18 is generated.
19 19  
20 20  
21   -read widgets3/widget.anubis
  21 + read widgets3/widget.anubis
  22 +read widget.anubis
22 23  
23 24 public define Widget
24 25 create_image
... ...
anubis_dev/library/widgets3/input.anubis
... ... @@ -14,8 +14,8 @@
14 14  
15 15  
16 16  
17   -read widgets3/widget.anubis
18   -read widgets3/tools.anubis
  17 +read widget.anubis
  18 +read tools.anubis
19 19  
20 20  
21 21 In this file, the 'input' widget is defined. The global term 'input' covers three
... ...
anubis_dev/library/widgets3/john_lackland.jpg 0 โ†’ 100644

54.3 KB

anubis_dev/library/widgets3/menu_manager.anubis
... ... @@ -12,8 +12,8 @@
12 12  
13 13  
14 14  
15   -read widgets3/widget.anubis
16   -read widgets3/tools.anubis
  15 +read widget.anubis
  16 +read tools.anubis
17 17  
18 18  
19 19 This widget provides a 'menu' facility which may be used by other widgets. In most
... ... @@ -118,8 +118,8 @@ public define MenuCommand
118 118 ---------------------------------------------------------------------------------------
119 119  
120 120  
121   -read widgets3/window.anubis
122   -read widgets3/box.anubis
  121 +read window.anubis
  122 +read box.anubis
123 123  
124 124 *** (1) Positioning a new menu.
125 125  
... ...
anubis_dev/library/widgets3/menus.anubis
... ... @@ -12,8 +12,8 @@
12 12  
13 13  
14 14  
15   -read widgets3/widget.anubis
16   -read widgets3/tools.anubis
  15 +read widget.anubis
  16 +read tools.anubis
17 17  
18 18  
19 19 This file contains tools for creating menus (to be put in the command variable of your
... ...
anubis_dev/library/widgets3/o_hypertext.anubis
... ... @@ -14,10 +14,13 @@
14 14  
15 15  
16 16  
17   -read widgets3/widget.anubis
18   -read widgets3/tools.anubis
  17 + read widgets3/widget.anubis
  18 + read widgets3/tools.anubis
  19 +read widget.anubis
  20 +read tools.anubis
19 21  
20   -read o_basis.anubis
  22 + read /home/olivier/anubis_dev/library/tools/basis.anubis
  23 +read tools/basis.anubis
21 24 read image.anubis
22 25  
23 26  
... ... @@ -103,23 +106,22 @@ public type WidgetTextEffect:
103 106  
104 107  
105 108 public type PosWidget:
106   - left_pos (Int32 v_pos, // vertical_position,
  109 + left_pw (Int32 v_pos, // vertical_position,
107 110 Int32 spacer, // spacer between the widget and the text against it
108 111 Widget wid),
109   - right_pos (Int32 v_pos, //vertical_position,
  112 + right_pw (Int32 v_pos, //vertical_position,
110 113 Int32 spacer, // spacer between the widget and the text against it
111 114 Widget wid).
112 115  
113 116 public type FloatingWidget:
114   - left (Int32 spacer, // spacer between the widget and the text against it
115   - Widget wid),
116   - right (Int32 spacer, // spacer between the widget and the text against it
117   - Widget wid).
  117 + left_fw (Int32 spacer, // spacer between the widget and the text against it
  118 + Widget wid),
  119 + right_fw (Int32 spacer, // spacer between the widget and the text against it
  120 + Widget wid).
118 121  
119 122 public type LinkWidget:
120   - link(String,
121   - RGB, // color for the link
122   - WidgetEventToolBox -> One). // action performed by the button
  123 + link(String txt,
  124 + WidgetEventToolBox -> One action). // action performed by the link
123 125  
124 126  
125 127 public type HyperTextContent:
... ... @@ -134,6 +136,13 @@ public type HyperTextContent:
134 136  
135 137 "This " + "photograph " + pos(-12,create_image("flowers.jpg")) + " was taken in Paris.".
136 138  
  139 +
  140 + Note 1 : caracter '&' is reserved. To have a '&' in your text, type '\&'.
  141 + Note 2 : spaces begening or ending a text and repeated spaces are remove. To have
  142 + surely a space, type '\ '.
  143 +
  144 +
  145 +
137 146  
138 147  
139 148  
... ... @@ -285,9 +294,11 @@ public define Widget
285 294 Int32 vertical_spacing, // number of pixels between lines
286 295 Int32 indent, // number of pixels before beginning of paragraphs
287 296 WidgetTextJustify justify, // how to justify the text
288   - HyperTextContent content
  297 + HyperTextContent content,
  298 + Maybe(RGB) link_color // failure if there is no links in hypertext
289 299 ).
290 300  
  301 + Note : if (WidgetTextJustify)center is choosen, the indentation will be not applied.
291 302  
292 303 Convenience functions:
293 304  
... ... @@ -310,7 +321,8 @@ public define Widget
310 321 1,
311 322 3,
312 323 left,
313   - text+empty).
  324 + text+empty,
  325 + failure).
314 326  
315 327  
316 328  
... ... @@ -331,7 +343,8 @@ public define Widget
331 343 3,
332 344 0,
333 345 center,
334   - text+empty).
  346 + text+empty,
  347 + failure).
335 348  
336 349  
337 350  
... ... @@ -350,13 +363,15 @@ type HyperTextParameters:
350 363 (
351 364 SystemFont font,
352 365 Int32 font_height,
  366 + Int32 font_depth,
353 367 Int32 total_font_height,
354 368 Int32 margin,
355 369 Int32 v_space,
356 370 Int32 indent,
357 371 WidgetTextEffect effect,
358 372 WidgetTextJustify justify,
359   - String -> Int32 string_width
  373 + String -> Int32 string_width,
  374 + RGB link_color
360 375 ).
361 376  
362 377  
... ... @@ -393,35 +408,40 @@ define List(String)
393 408  
394 409  
395 410  
396   - *** (2.2) Is last paragraph line ?
397   - **********************************
  411 + *** (2.2) Text color
  412 + ********************
398 413  
399   - The purpose is to check is a string is the last line of a paragraph, i.e. the last
400   - caracters of the string are '\t'.
  414 +define RGB
  415 + text_color
  416 + (
  417 + WidgetTextEffect effect
  418 + ) =
  419 + if effect is
  420 + {
  421 + normal(c) then c,
  422 + shadow(c,_,_,_) then c,
  423 + engraved(c) then c,
  424 + relief(c) then c
  425 + }.
401 426  
  427 +
402 428  
403   -define Bool
404   - is_ending_paragraph
  429 +define One
  430 + print_ls
405 431 (
406   - String s
407   - ) = print("["+s+"]");
408   - if reverse(explode(s)) is
  432 + List(String) ls
  433 + ) =
  434 + if ls is
409 435 {
410   - [] then false,
411   - [h . t] then //h = truncate_to_int8(10)}.
412   - if h = 'n'
413   - then if t is
414   - {
415   - [] then false,
416   - [u . v] then u = '\'
417   - }
418   - else false
  436 + [] then unique,
  437 + [h . t] then print("["+h+"]\n");print_ls(t)
419 438 }.
420 439  
421   - *** (3) Width of the hypertext
422   - ******************************
423 440  
424   - To construct the hypertext a max widht is required. But this number could be higher if
  441 + *** (3) Width of the content of the hypertext
  442 + *********************************************
  443 +
  444 + To construct the hypertext a max width is required. But this number could be higher if
425 445 the width of a sub-widget is greater. So the real width must be computed.
426 446  
427 447  
... ... @@ -458,8 +478,8 @@ define Int32
458 478  
459 479 To print the hypertext, its content will be transform into 'blocks'. Two kinds of
460 480 block are defined according to the content :
461   - .1: block with only text all along the width of then widget;
462   - .2: block with a widget and text against it, if the width of the widget allows it.
  481 + .1: block with only text all along the width of the hypertext;
  482 + .2: block with a widget and text against it (text may be empty)
463 483  
464 484  
465 485 +---------- Hypertext ---------------------------+
... ... @@ -485,162 +505,621 @@ define Int32
485 505 +------------------------------------------------+
486 506  
487 507  
488   - Note 1 : a block could contain only one widget.
489   - Note 2 :
  508 + Note : a block could contain only one widget.
  509 +
  510 +
  511 +
  512 +
  513 + The text contained in a block are paragraphs. Those paragraphs are transformed into a
  514 + List(BlockLine) to distinguish the different kind of lines that exist in a
  515 + paragraph. And for each one, the indent and both justify (if required) parameters will
  516 + be different.
  517 +
  518 + Those kinds of lines are (names of BlockLine alternatives):
  519 +
  520 + +--------+------------------------------------------------+--------+-------------------+
  521 + | name | Definition | indent | justify |
  522 + +--------+------------------------------------------------+--------+-------------------+
  523 + | first | first line of paragraph | yes | yes |
  524 + +--------+------------------------------------------------+--------+-------------------+
  525 + | middle | middle line of paragraph | no | yes |
  526 + +--------+------------------------------------------------+--------+-------------------+
  527 + | last | last line of paragraph | no | no, even required |
  528 + +--------+------------------------------------------------+--------+-------------------+
  529 + | flast | only line of a paragraph : both first and last | yes | no, even required |
  530 + +--------+------------------------------------------------+--------+-------------------+
  531 +
  532 +
  533 +
  534 + There is an exception : the text against a position_widget will be not indented and not
  535 + justified. We take on this arbitrary choice !
  536 +
490 537  
491 538  
492 539 So, here is the type 'Block' :
493 540  
494   -
  541 +type BlockContent:
  542 + empty,
  543 + text (String, // words,
  544 + BlockContent),
  545 + link (String, // words,
  546 + WidgetEventToolBox -> One, // action,
  547 + Int32, // index
  548 + BlockContent).
  549 +
  550 +
  551 +define BlockContent
  552 + BlockContent bc1 + BlockContent bc2 =
  553 + if bc1 is
  554 + {
  555 + empty then bc2,
  556 + text(w,bc) then text(w,bc+bc2),
  557 + link(w,a,i,bc) then link(w,a,i,bc+bc2)
  558 + }.
  559 +
  560 +
  561 +type BlockLine:
  562 + first (BlockContent cont),
  563 + middle (BlockContent cont),
  564 + last (BlockContent cont),
  565 + flast (BlockContent cont).
  566 +
  567 +
495 568 type LR_Widget:
496 569 left,
497 570 right.
498 571  
  572 +
499 573 type Block:
500   - t_block (List(List(String))),
501   - wt_block (List(List(String)),
  574 + t_block (List(BlockLine)),
  575 + wt_block (List(BlockLine),
502 576 LR_Widget,
503   - Int32, // vertical position of the text from the top of the widget
504   - Int32, // spacer between the widget and the text against it
  577 + Int32, // vertical position
  578 + Int32, // spacer between the widget and the text agains it
505 579 Widget).
506 580  
507   -
508   - Each alternative contains a List(List(String)) for the text which is understood as
509   - paragraphs.
510 581  
511   - For 'wt_block()', we need to known for printing the geographical position (left or
512   - right) of the widget.
  582 +
  583 + The alternative 'wt_block', which is for blocks containing widget, contains, as well as
  584 + the widget itself, three other parameters :
  585 + . LR_Widget to place the widget to the left or to the right of the hypertext
  586 + . an Int32 for the vertical position of the text from the top of the widget; this is
  587 + only for a position widget, the value is 0 for an floating-widget.
  588 + . an Int32 for spacing the widget to the text against it
513 589  
514 590  
515 591  
516 592 *** (4.2) HyperTextContent -> List(Blocks)
517 593 ******************************************
518 594  
  595 +define String
  596 + concat_bcont
  597 + (
  598 + BlockContent bc
  599 + ) =
  600 + if bc is
  601 + {
  602 + empty then "",
  603 + text(s,b) then s+concat_bcont(b),
  604 + link(s,a,i,b) then s+concat_bcont(b),
  605 + }.
  606 +
  607 +define String
  608 + print_bl
  609 + (
  610 + List(BlockLine) lbl
  611 + ) =
  612 + if lbl is
  613 + {
  614 + [] then "",
  615 + [h . t] then concat_bcont(cont(h))+"|"+print_bl(t)
  616 + }.
519 617  
520   - *** (4.2.1) Transform the text to a List(String)
521   - ************************************************
  618 + *** (4.2.1) Transform the text to List(BlockLine)
  619 + *************************************************
522 620  
523 621  
  622 + 'StringParagraph' is used to store the text, whithout any transformation, when the
  623 + HyperTextContent is reading to become blocks (function 'to_blocks'). The text come from
  624 + the content itself, and from the part of the text not used when block are build
  625 + (example : unused text after a position widget).
  626 +
  627 + So, StringParagraph has two alternatives to know if the text in it begins a paragraph
  628 + or if it's just the same a before.
  629 +
  630 +
  631 +type StringParagraph:
  632 + new_paragraph (String text),
  633 + to_continue (String text),
  634 + new_paragraph (LinkWidget lwid,
  635 + Int32 index),
  636 + to_continue (LinkWidget lwid,
  637 + Int32 index).
  638 +
  639 +
  640 +define List(StringParagraph)
  641 + add
  642 + (
  643 + List(StringParagraph) lsp,
  644 + String s
  645 + ) =
  646 + if lsp is
  647 + {
  648 + [] then [new_paragraph(s)],
  649 + [h . t] then
  650 + if h is
  651 + {
  652 + /*
  653 + new_paragraph(p) then print("h=npt"+s+"\n");[new_paragraph(p+s) . t],
  654 + to_continue(p) then print("h=tct"+s+"\n");[to_continue(p+s) . t],
  655 + new_paragraph(_,_) then print("h=npl"+s+"\n");[to_continue(s) . lsp],
  656 + to_continue(_,_) then print("h=tcl"+s+"\n");[to_continue(s) . lsp]
  657 + */
  658 + new_paragraph(p) then [new_paragraph(p+s) . t],
  659 + to_continue(p) then [to_continue(p+s) . t],
  660 + new_paragraph(_,_) then [to_continue(s) . lsp],
  661 + to_continue(_,_) then [to_continue(s) . lsp]
  662 + }
  663 + }.
  664 +
  665 +define List(StringParagraph)
  666 + add
  667 + (
  668 + List(StringParagraph) lsp,
  669 + LinkWidget lw,
  670 + Int32 i
  671 + ) =
  672 + if lsp is
  673 + {
  674 + [] then [new_paragraph(lw,i)],
  675 + [h . t] then [to_continue(lw,i) . lsp]
  676 + }.
  677 +
  678 +
  679 +
524 680 *** (4.2.1.1) From text only
525 681 ****************************
526 682  
527   - Several steps for transforming a text to a List(String) for a block.
528   -
529   - First, the text is split into lines according to what it is required by the source (see
530   - tools.anubis for this transformation).
  683 + This function is used to transform a text into a List(BlockLine) when it comes from the
  684 + HyperTextContent alternative 'string'. The result will be List(BlockLine) of type 1.
531 685  
  686 +
532 687  
  688 + Several steps for transforming a text to a List(String) for a block.
533 689  
534   - 'max_width' is the hypertext width or the avaliable width at the left or the right of
535   - the widget.
  690 + First, the text is split into lines according to what it is required by the source (see
  691 + tools.anubis for this transformation). This operatation gives a List(String) where each
  692 + string is a paragraph.
536 693  
537   - 'lines' are computed from what's required by user : each string in it is ending by a
538   - linefeed (except possibly the last one).
  694 + Then each string (or paragraph) are cut to a List(BlockLine) according to the width of
  695 + the hypertext, less the indentation for the first one.
539 696  
540 697  
541 698  
542   -define List(String)
  699 +define (List(BlockLine),BlockContent,String -> Bool)
543 700 transforming_text
544   - (
545   - String line,
546   - Int32 i,
547   - String -> Bool is_too_large_test,
548   - String word,
549   - String words_line,
550   - List(String) so_far,
551   - String -> Bool is_too_large,
552   - ) =
  701 + (
  702 + String line,
  703 + BlockContent bc,
  704 + Int32 i,
  705 + String -> Bool is_too_large_c,
  706 + String -> Bool is_too_large,
  707 + (BlockContent,String) -> BlockLine to_bline, // the active function
  708 + String word,
  709 + String words_line,
  710 + (BlockContent,String) -> BlockLine to_middle,
  711 + String -> BlockContent to_bcont,
  712 + List(BlockLine) so_far
  713 + ) = //print("bc=["+concat_bcont(bc)+"]\n");
553 714 if nth(i,line) is
554 715 {
555 716 failure then
556 717 with new_words_line = (String)(words_line+" "+word),
557   - if is_too_large_test(new_words_line)
558   - then so_far+[words_line,word]
559   - else so_far+[new_words_line],
  718 + bc_and_line = (String)(concat_bcont(bc)+new_words_line),
  719 + if is_too_large_c(bc_and_line)
  720 + then //print("bal=["+bc_and_line+"]\n");
  721 + //print("bc=["+concat_bcont(bc)+"]\n");
  722 + //print("wl=["+words_line+"]\n");
  723 + /*
  724 + if bc is
  725 + {
  726 + empty then print("EMPTY \n"),
  727 + text(_,_) then print("TEXT \n"),
  728 + link(_,_,_,_,_) then print("LINK \n")
  729 + };
  730 + if to_bcont(words_line) is
  731 + {
  732 + empty then print("EMPTY \n"),
  733 + text(_,_) then print("TEXT \n"),
  734 + link(_,_,_,_,_) then print("LINK \n")
  735 + };
  736 + */
  737 + //([to_middle(bc,words_line) . so_far],last_bc(word))
  738 + ([middle(bc+to_bcont(words_line)) . so_far],to_bcont(word),is_too_large_c)
  739 + //else (so_far,last_bc(new_words_line))
  740 + else (so_far,to_bcont(bc_and_line),is_too_large_c)
560 741 success(c) then
561 742 if c = ' '
562 743 then // the test on 'words_line' is to avoid a space as first character to begin
563 744 // the all text to print
564 745 with new_words_line = (String)(words_line+(if words_line = "" then "" else " ")+word),
565   - if is_too_large_test(new_words_line)
566   - then transforming_text(line,i+1,is_too_large,"",word,so_far+[words_line],is_too_large)
567   - else transforming_text(line,i+1,is_too_large_test,"",new_words_line,so_far,is_too_large)
568   - else transforming_text(line,i+1,is_too_large_test,word+implode([c]),words_line,so_far,
569   - is_too_large)
  746 + //with new_words_line = (String)(words_line+word),
  747 + if is_too_large_c(new_words_line+concat_bcont(bc))
  748 + then //print("too_large = ["+new_words_line+concat_bcont(bc)+"]\n");
  749 + //print("nwl=["+new_words_line+"]\n");
  750 + //print("wl=["+words_line+"]\n");
  751 + //print("bc=["+concat_bcont(bc)+"]\n");
  752 + //print("lbl=["+print_bl([to_bline(bc,words_line)])+"]\n");
  753 + transforming_text(line,empty,i+1,is_too_large,is_too_large,to_middle,
  754 + word+" ","",to_middle,to_bcont,
  755 + [to_bline(bc,words_line) . so_far])
  756 + else //print("not_too_large = ["+new_words_line+concat_bcont(bc)+"]\n");
  757 + transforming_text(line,bc,i+1,is_too_large_c,is_too_large,to_bline,
  758 + "",new_words_line,to_middle,to_bcont,so_far)
  759 + else transforming_text(line,bc,i+1,is_too_large_c,is_too_large,to_bline,
  760 + word+implode([c]),words_line,to_middle,to_bcont,so_far)
570 761 }.
571 762  
572   -define List(String)
  763 +
  764 +
  765 +define (List(BlockLine),BlockContent,String -> Bool)
573 766 transforming_text
574 767 (
575   - String line,
576   - Int32 i,
577   - String -> Bool is_too_large,
578   - String word,
579   - String words_line,
580   - List(String) so_far
  768 + List(String) lines, // 1 line = text_paragraph
  769 + BlockContent bc,
  770 + String -> Bool is_too_large_i,
  771 + String -> Bool is_too_large,
  772 + (BlockContent,String) -> BlockLine to_bline, // initialized according to str_paragraph
  773 + (BlockContent,String) -> BlockLine to_flast, // .. same ..
  774 + (BlockContent,String) -> BlockLine to_middle,
  775 + (BlockContent,String) -> BlockLine to_first,
  776 + (BlockContent,String) -> BlockLine to_last,
  777 + String -> BlockContent to_bcont,
  778 + BlockContent -> BlockLine bc_to_bl,
  779 + List(BlockLine) so_far
581 780 ) =
582   - if nth(i,line) is
583   - {
584   - failure then
585   - with new_words_line = (String)(words_line+" "+word),
586   - if is_too_large(new_words_line)
587   - then so_far+[words_line,word]
588   - else so_far+[new_words_line],
589   - success(c) then
590   - if c = ' '
591   - then // the test on 'words_line' is to avoid a space as first character to begin
592   - // the all text to print
593   - with new_words_line = (String)(words_line+(if words_line = "" then "" else " ")+word),
594   - if is_too_large(new_words_line)
595   - then transforming_text(line,i+1,is_too_large,"",word,so_far+[words_line])
596   - else transforming_text(line,i+1,is_too_large,"",new_words_line,so_far)
597   - else transforming_text(line,i+1,is_too_large,word+implode([c]),words_line,so_far)
  781 + if lines is
  782 + {
  783 + [] then (so_far,bc,is_too_large_i),
  784 + [h . t] then //print("h=["+h+"]\n");
  785 + with new_bc = to_bcont(h),
  786 + add_bc = bc+new_bc,
  787 + if is_too_large_i(concat_bcont(add_bc))
  788 + then //print("ADD BC=["+concat_bcont(add_bc)+"]\n");
  789 + (if transforming_text
  790 + (h,bc,0,is_too_large_i,is_too_large,to_bline,
  791 + if bc is empty then "" else " ","",
  792 + if t is [] then to_middle /*to_last*/else to_middle,to_bcont,[])
  793 + is (new_lbl,new_bc,current_test) then
  794 +
  795 + if t is []
  796 + then // in this case, it's ne
  797 + (new_lbl+so_far,new_bc,current_test)
  798 + else // in this case, bc will be add to lbl (h is a real paragraph)
  799 + transforming_text(t,empty,is_too_large_i,is_too_large,to_first,
  800 + to_flast,to_middle,to_first,to_last,to_bcont,
  801 + bc_to_bl,[bc_to_bl(new_bc) . new_lbl]+so_far))
  802 +
  803 + else if t is []
  804 + then (so_far,add_bc,is_too_large_i)
  805 + else transforming_text(t,empty,is_too_large_i,is_too_large,to_first,
  806 + to_flast,to_middle,to_first,to_last,to_bcont,
  807 + bc_to_bl,[to_flast(add_bc,"")]+so_far)
598 808 }.
  809 +
  810 + else transforming_text(t,empty,is_too_large_i,is_too_large,to_first,
  811 + to_flast,to_middle,to_first,to_last,to_bcont,
  812 + bc_to_bl,[to_flast(add_bc,"")]+so_far)
  813 + else transforming_text(t,add_bc,is_too_large_i,is_too_large,to_first,
  814 + to_flast,to_middle,to_first,to_last,to_bcont,
  815 + bc_to_bl,so_far)
599 816  
600 817  
601   -define List(List(String))
  818 +
  819 +define Bool
  820 + is_next_continue
  821 + (
  822 + List(StringParagraph) l
  823 + ) =
  824 + if l is
  825 + {
  826 + [] then false,
  827 + [h . _] then true
  828 + }.
  829 + if h is
  830 + {
  831 + new_paragraph(txt) then false,
  832 + to_continue(txt) then true,
  833 + new_paragraph(lk,i) then false,
  834 + to_continue(lk,i) then true,
  835 + }
  836 +
  837 +
  838 +
  839 +
  840 +define (List(BlockLine),String -> Bool)
602 841 transforming_text
603 842 (
604   - List(String) lines,
605   - String -> Bool is_too_large1, // for the first line (with indent)
  843 + List(StringParagraph) lstr_pgraph,
  844 + String -> Bool is_too_large_i, // for the first line (with indent)
  845 + String -> Bool is_too_large,
  846 + BlockContent b_cont,
  847 + List(BlockLine) so_far_lbl,
  848 + String -> Bool last_used_test
  849 + ) =
  850 + if lstr_pgraph is
  851 + {
  852 + [] then
  853 + (if b_cont is
  854 + {
  855 + empty then [],
  856 + text(s,bc) then append(so_far_lbl,[last(text(s,empty))]),
  857 + link(s,a,i,bc) then append(so_far_lbl,[last(link(s,a,i,empty))])
  858 + },last_used_test),
  859 + [h . t] then
  860 + if h is
  861 + {
  862 + new_paragraph(txt) then //print("NP_t ["+txt+"]\n");
  863 + //print("NP_t/bcont=["+concat_bcont(b_cont)+"]\n");
  864 + if transforming_text
  865 + (split_string_into_lines(txt),b_cont,is_too_large_i,is_too_large,
  866 + (BlockContent bc,String s) |-> first(bc+text(s,empty)),
  867 + (BlockContent bc,String s) |-> flast(bc+text(s,empty)),
  868 + (BlockContent bc,String s) |-> middle(bc+text(s,empty)),
  869 + (BlockContent bc,String s) |-> first(bc+text(s,empty)),
  870 + (BlockContent bc,String s) |-> last(bc+text(s,empty)),
  871 + (String s) |-> text(s,empty),
  872 + (BlockContent bc) |-> last(bc),
  873 + (List(BlockLine))[]) is (new_lbl,new_bc,last_test) then
  874 + //print("NP_t/new_bc=["+concat_bcont(new_bc)+"]\n");
  875 + // append(reverse(new_lbl),
  876 + // transforming_text(t,is_too_large_i,is_too_large,new_bc,last_test)),
  877 + transforming_text(t,is_too_large_i,is_too_large,new_bc,
  878 + append(so_far_lbl,reverse(new_lbl)),last_test),
  879 +
  880 + to_continue(txt) then //print("TC_t ["+txt+"]\n");
  881 + //print("TT=");print_ls(split_string_into_lines(txt));print("\n");
  882 + //print("TC_t/bcont=["+concat_bcont(b_cont)+"]\n");
  883 + if transforming_text
  884 + (split_string_into_lines(txt),b_cont,is_too_large,is_too_large,
  885 + (BlockContent bc,String s) |-> middle(bc+text(s,empty)),
  886 + (BlockContent bc,String s) |-> flast(bc+text(s,empty)),
  887 + (BlockContent bc,String s) |-> middle(bc+text(s,empty)),
  888 + (BlockContent bc,String s) |-> first(bc+text(s,empty)),
  889 + (BlockContent bc,String s) |-> last(bc+text(s,empty)),
  890 + (String s) |-> text(s,empty),
  891 + (BlockContent bc) |-> middle(bc),
  892 + (List(BlockLine))[]) is (new_lbl,new_bc,last_test) then
  893 + //print("TC_t/new_bc=["+concat_bcont(new_bc)+"]\n");
  894 + // append(reverse(new_lbl),
  895 + // transforming_text(t,is_too_large_i,is_too_large,new_bc,last_test)),
  896 + transforming_text(t,is_too_large_i,is_too_large,new_bc,
  897 + append(so_far_lbl,reverse(new_lbl)),last_test),
  898 +
  899 + new_paragraph(lk,i) then print("NP_l ["+txt(lk)+"]\n");
  900 + if transforming_text
  901 + (split_string_into_lines(txt(lk)),b_cont,is_too_large_i,is_too_large,
  902 + (BlockContent bc,String s) |-> first(bc+link(s,action(lk),i,empty)),
  903 + (BlockContent bc,String s) |-> flast(bc+link(s,action(lk),i,empty)),
  904 + (BlockContent bc,String s) |-> middle(bc+link(s,action(lk),i,empty)),
  905 + (BlockContent bc,String s) |-> first(bc+link(s,action(lk),i,empty)),
  906 + (BlockContent bc,String s) |-> last(bc+link(s,action(lk),i,empty)),
  907 + (String s) |-> link(s,action(lk),i,empty),
  908 + (BlockContent bc) |-> middle(bc),
  909 + (List(BlockLine))[]) is (new_lbl,new_bc,last_test) then
  910 + //print("NP_l/new_bc=["+concat_bcont(new_bc)+"]\n");
  911 + // append(reverse(new_lbl),
  912 + // transforming_text(t,is_too_large_i,is_too_large,new_bc,last_test)),
  913 + transforming_text(t,is_too_large_i,is_too_large,new_bc,
  914 + append(so_far_lbl,reverse(new_lbl)),last_test),
  915 +
  916 + to_continue(lk,i) then //print("TC_l ["+txt(lk)+"]\n"); print("lt="+length(t)+"\n");
  917 + //print("TC_l/bcont=["+concat_bcont(b_cont)+"]\n");
  918 + if transforming_text
  919 + (split_string_into_lines(txt(lk)),b_cont,is_too_large,is_too_large,
  920 + (BlockContent bc,String s) |-> middle(bc+link(s,action(lk),i,empty)),
  921 + (BlockContent bc,String s) |-> flast(bc+link(s,action(lk),i,empty)),
  922 + (BlockContent bc,String s) |-> middle(bc+link(s,action(lk),i,empty)),
  923 + (BlockContent bc,String s) |-> first(bc+link(s,action(lk),i,empty)),
  924 + (BlockContent bc,String s) |-> last(bc+link(s,action(lk),i,empty)),
  925 + (String s) |-> link(s,action(lk),i,empty),
  926 + (BlockContent bc) |-> middle(bc),
  927 + (List(BlockLine))[]) is (new_lbl,new_bc,last_test) then
  928 + //print("TC_l/new_bc=["+concat_bcont(new_bc)+"]\n");
  929 + // append(reverse(new_lbl),
  930 + // transforming_text(t,is_too_large_i,is_too_large,new_bc,last_test)),
  931 + transforming_text(t,is_too_large_i,is_too_large,new_bc,
  932 + append(so_far_lbl,reverse(new_lbl)),last_test),
  933 + }
  934 + }.
  935 +
  936 +
  937 +define List(BlockLine)
  938 + transforming_text
  939 + (
  940 + List(StringParagraph) lstr_pgraph,
  941 + String -> Bool is_too_large_i, // for the first line (with indent)
  942 + String -> Bool is_too_large
  943 + ) =
  944 + if transforming_text(lstr_pgraph,is_too_large_i,is_too_large,empty,[],is_too_large_i)
  945 + is (lbl,_) then lbl.
  946 +
  947 +
  948 + transforming_text(lstr_pgraph,is_too_large_i,is_too_large,empty).
  949 + transforming_text(lstr_pgraph,is_too_large_i,is_too_large,is_next_continue(lstr_pgraph),1).
  950 +
  951 +
  952 +
  953 +
  954 + *** (4.2.1.2) From text before a floating-widget
  955 + ************************************************
  956 +
  957 +
  958 +
  959 + The string-line of text before a floating-widget must be as larger as possible. To
  960 + reached this, it could be necessary to make up this line with the text containing into
  961 + the floating-widget.
  962 +
  963 + First, the text given by the hypertext-content preceding the floating-widget is
  964 + transform into a List(BlockLine).
  965 +
  966 + Then, the last BlockLine is maked up to obtain a full string-line according to the
  967 + available width, the unused text will be transformed elsewhere to take place against
  968 + the widget.
  969 +
  970 + Note : the first tranformation returns the last test on the width (is_too_large)
  971 + because for making-up the line it's necessary to know if is a line with indent or not.
  972 +
  973 +
  974 +define (String,String)
  975 + make_up_the_line
  976 + (
  977 + List(Int8) new_s,
  978 + String word,
  979 + String add_words,
606 980 String -> Bool is_too_large
607 981 ) =
608   - if lines is
  982 + if new_s is
609 983 {
610   - [] then [],
611   - [h . t] then
612   - if is_too_large(h)
613   - then [transforming_text(h,0,is_too_large1,"","",[],is_too_large)
614   - . transforming_text(t,is_too_large1,is_too_large)]
615   - else [[h] . transforming_text(t,is_too_large1,is_too_large)]
  984 + [] then
  985 + with last_line = (String)(add_words+" "+word),
  986 + if is_too_large(last_line)
  987 + then (add_words,word)
  988 + else (last_line,""),
  989 + [c . t] then
  990 + if c = ' '
  991 + then with last_line = (String)(add_words+" "+word),
  992 + if is_too_large(last_line)
  993 + then (add_words,word+" "+implode(t))
  994 + else make_up_the_line(t,"",last_line,is_too_large)
  995 + else make_up_the_line(t,word+implode([c]),add_words,is_too_large)
616 996 }.
617 997  
  998 +define (String,String)
  999 + make_up_the_line
  1000 + (
  1001 + String new_s,
  1002 + String for_make_up,
  1003 + String -> Bool is_too_large
  1004 + ) =
  1005 + make_up_the_line(explode(new_s),"","",(String s) |-> is_too_large(for_make_up+s)).
618 1006  
  1007 +
  1008 + define (BlockLine,HyperTextContent,Int32)
  1009 + transforming_text_before_fw
  1010 + (
  1011 + HyperTextContent next_htc, // after the current floating-widget
  1012 + String -> Bool is_too_large,
  1013 + BlockContent bc,
  1014 + BlockContent -> BlockLine to_bl,
  1015 + Int32 nb_lk
  1016 + ) =
  1017 + if next_htc is
  1018 + {
  1019 + empty then (to_bl(bc),empty,nb_lk),
  1020 + string(s,htc) then
  1021 + if make_up_the_line(s,concat_bcont(bc),is_too_large)
  1022 + is (made_up,more_words) then
  1023 + //print("MW="+more_words+"\n");
  1024 + if more_words = ""
  1025 + then transforming_text_before_fw(htc,is_too_large,bc+text(made_up,empty),to_bl,nb_lk)
  1026 + else (to_bl(bc+text(made_up,empty)),string(more_words,htc),nb_lk)
  1027 + linkw(lw,htc) then //(last(empty),linkw(lw,htc)),
  1028 + if make_up_the_line(txt(lw),concat_bcont(bc),is_too_large)
  1029 + is (made_up,more_words) then
  1030 + if more_words = ""
  1031 + then transforming_text_before_fw
  1032 + (htc,is_too_large,bc+link(made_up,action(lw),nb_lk,empty),to_bl,nb_lk+1)
  1033 + else (to_bl(bc+link(made_up,action(lw),nb_lk,empty)),
  1034 + linkw(link(more_words,action(lw)),htc),nb_lk),
  1035 + posw(pw,htc) then (last(empty),posw(pw,htc),nb_lk),
  1036 + floatingw(fw,htc) then (last(empty),floatingw(fw,htc),nb_lk)
  1037 + }.
619 1038  
620 1039  
621   -define One
622   - print_ls
  1040 +define (BlockLine,HyperTextContent,StringParagraph,Int32)
  1041 + transforming_text_before_fw
623 1042 (
624   - List(String) ls
  1043 + HyperTextContent next_htc, // after the current floating-widget
  1044 + String -> Bool is_too_large,
  1045 + BlockContent bc,
  1046 + BlockContent -> BlockLine to_bl,
  1047 + Int32 nb_lk
625 1048 ) =
626   - if ls is
  1049 + if next_htc is
627 1050 {
628   - [] then unique,
629   - [h . t] then print("["+h+"]\n");print_ls(t)
  1051 + empty then (to_bl(bc),empty,new_paragraph(""),nb_lk),
  1052 + string(s,htc) then
  1053 + if make_up_the_line(s,concat_bcont(bc),is_too_large)
  1054 + is (made_up,more_words) then
  1055 + //print("MW="+more_words+"\n");
  1056 + if more_words = ""
  1057 + then transforming_text_before_fw(htc,is_too_large,bc+text(made_up,empty),to_bl,nb_lk)
  1058 + else (to_bl(bc+text(made_up,empty)),htc,to_continue(more_words),nb_lk)
  1059 + linkw(lw,htc) then //(last(empty),linkw(lw,htc)),
  1060 + if make_up_the_line(txt(lw),concat_bcont(bc),is_too_large)
  1061 + is (made_up,more_words) then
  1062 + if more_words = ""
  1063 + then transforming_text_before_fw
  1064 + (htc,is_too_large,bc+link(made_up,action(lw),nb_lk,empty),to_bl,nb_lk+1)
  1065 + else (to_bl(bc+link(made_up,action(lw),nb_lk,empty)),
  1066 + htc,to_continue(link(more_words,action(lw)),nb_lk),nb_lk),
  1067 + posw(pw,htc) then (last(empty),posw(pw,htc),new_paragraph(""),nb_lk),
  1068 + floatingw(fw,htc) then (last(empty),floatingw(fw,htc),new_paragraph(""),nb_lk)
630 1069 }.
631 1070  
632   -define List(List(String))
633   - transforming_text
  1071 +
  1072 +
  1073 +
  1074 +define (List(BlockLine),HyperTextContent,List(StringParagraph),Int32)
  1075 + transforming_text_before_fw
634 1076 (
635   - String text,
636   - String -> Bool is_too_large1,
637   - String -> Bool is_too_large
  1077 + List(BlockLine) new_blines, // reversed
  1078 + HyperTextContent next_htc, // after the current floating-widget
  1079 + String -> Bool is_too_large,
  1080 + ) =
  1081 + if new_blines is
  1082 + {
  1083 + [] then ([],next_htc,[],0),
  1084 + [last . t] then
  1085 + if last is
  1086 + {
  1087 + first(bc) then //print("FIRST\n");
  1088 + if transforming_text_before_fw(next_htc,is_too_large,bc,(BlockContent b) |-> first(b),0)
  1089 + is (bl,more_htc,sp,nb_lk)
  1090 + //then (reverse([bl . t]),more_htc,[to_continue("")],nb_lk),
  1091 + then (reverse([bl . t]),more_htc,[sp],nb_lk),
  1092 + middle(bc) then //print("MIDDLE\n");
  1093 + if transforming_text_before_fw(next_htc,is_too_large,bc,(BlockContent b) |-> middle(b),0)
  1094 + is (bl,more_htc,sp,nb_lk)
  1095 + //then (reverse([bl . t]),more_htc,[to_continue("")],nb_lk),
  1096 + then (reverse([bl . t]),more_htc,[sp],nb_lk),
  1097 + last(bc) then //print("LAST\n"); //(reverse(new_blines),next_htc,[]),
  1098 + if transforming_text_before_fw(next_htc,is_too_large,bc,(BlockContent b) |-> middle(b),0)
  1099 + is (bl,more_htc,sp,nb_lk)
  1100 + //then (reverse([bl . t]),more_htc,[to_continue("")],nb_lk),
  1101 + then (reverse([bl . t]),more_htc,[sp],nb_lk),
  1102 + flast(_) then print("FLAST\n"); (reverse(new_blines),next_htc,[],0),
  1103 + }
  1104 + }.
  1105 +
  1106 +
  1107 +define (List(BlockLine),HyperTextContent,List(StringParagraph),Int32)
  1108 + transforming_text_before_fw
  1109 + (
  1110 + List(StringParagraph) lstr_pgraph,
  1111 + HyperTextContent next_htc, // after the current floating-widget
  1112 + String -> Bool is_too_large_i,
  1113 + String -> Bool is_too_large
638 1114 ) =
639   - //print_ls(split_string_into_lines(text));
640   - transforming_text(split_string_into_lines(text),is_too_large1,is_too_large).
  1115 + if ((List(BlockLine),String -> Bool))
  1116 + transforming_text(lstr_pgraph,is_too_large_i,is_too_large,empty,[],is_too_large_i) is
  1117 + (new_blines,is_too_l) then
  1118 +
  1119 + transforming_text_before_fw(reverse(new_blines),next_htc,is_too_l).
641 1120  
642 1121  
643   - *** (4.2.1.2) From a position-widget
  1122 + *** (4.2.1.3) From a position-widget
644 1123 ************************************
645 1124  
646 1125  
... ... @@ -655,10 +1134,12 @@ define List(List(String))
655 1134  
656 1135  
657 1136  
  1137 +
658 1138 define (String,String)
659 1139 posw_transforming_text
660 1140 (
661   - List(Int8) line,
  1141 + List(Int8) line,
  1142 + String b_cont,
662 1143 Int32 i,
663 1144 String -> Bool is_too_large,
664 1145 String word,
... ... @@ -668,137 +1149,623 @@ define (String,String)
668 1149 {
669 1150 [] then
670 1151 with new_words_line = (String)(words_line+" "+word),
671   - if is_too_large(new_words_line)
  1152 + if is_too_large(new_words_line+b_cont)
672 1153 then (words_line,word)
673 1154 else (new_words_line,""),
674 1155 [c . t] then
675 1156 if c = ' '
676 1157 then // the test on 'words_line' is to avoid a space as first character to begin
677 1158 // the all text to print
678   - with new_words_line = (String)(words_line+(if words_line = "" then "" else " ")+word),
679   - if is_too_large(new_words_line)
  1159 + with new_words_line =
  1160 + (String)(words_line+(if (words_line = "" & b_cont="") then "" else " ")+word),
  1161 + //with new_words_line = (String)(words_line+" "+word),
  1162 + if is_too_large(new_words_line+b_cont)
680 1163 then (words_line,word+" "+implode(t))
681   - else posw_transforming_text(t,i+1,is_too_large,"",new_words_line)
682   - else posw_transforming_text(t,i+1,is_too_large,word+implode([c]),words_line)
  1164 + else posw_transforming_text(t,b_cont,i+1,is_too_large,"",new_words_line)
  1165 + else posw_transforming_text(t,b_cont,i+1,is_too_large,word+implode([c]),words_line)
683 1166 }.
684 1167  
685   -define (List(List(String)),String)
  1168 +
  1169 +define (List(BlockLine),List(StringParagraph),BlockContent,Bool)
686 1170 posw_transforming_text
687 1171 (
688   - String text,
689   - String -> Bool is_too_large
  1172 + List(String) lines,
  1173 + BlockContent bc,
  1174 + String -> Bool is_too_large,
  1175 + String -> BlockContent to_bcont,
  1176 + String -> StringParagraph to_new,
  1177 + String -> StringParagraph to_cont,
690 1178 ) =
691   - if split_string_into_lines(text) is
  1179 + if lines is
692 1180 {
693   - [] then ([],""),
  1181 + [] then ([],[],empty,true),
694 1182 [line1 . others] then
695   - if posw_transforming_text(explode(line1),0,is_too_large,"","")
696   - is (against_widget,more) then
697   - ([[against_widget]],more+if others is [] then "" else "\n"+concat(others))
  1183 + //print("line1=["+line1+"]\n");
  1184 + with add_bc = bc+to_bcont(line1),
  1185 + //print("bc=["+concat_bcont(bc)+"]\n");
  1186 + //print("add_bc=["+concat_bcont(add_bc)+"]\n");
  1187 + if is_too_large(concat_bcont(add_bc))
  1188 + then
  1189 + (if posw_transforming_text(explode(line1),concat_bcont(bc),0,is_too_large,"","")
  1190 + is (against_widget,more) then
  1191 + with new_bc = bc+to_bcont(against_widget),
  1192 + //print("AW=["+against_widget+"] more=["+more+"]\n");
  1193 + //print("new_bc=["+concat_bcont(new_bc)+"]\n");
  1194 + ([last(new_bc)],
  1195 + [if more = "" // the line is to make up
  1196 + then to_new(concat(others))
  1197 + else to_cont(more+(if others is [] then "" else "\n"+concat(others)))],
  1198 + new_bc,
  1199 + true))
  1200 + else ([],[to_cont(concat(others))],add_bc,false)
  1201 +
  1202 + }.
  1203 +
  1204 +define (List(BlockLine),List(StringParagraph))
  1205 + posw_transforming_text
  1206 + (
  1207 + List(StringParagraph) lstr_pgraph,
  1208 + BlockContent build_bc,
  1209 + String -> Bool is_too_large_i,
  1210 + String -> Bool is_too_large,
  1211 + List(BlockLine) blines,
  1212 + List(StringParagraph) spars
  1213 + ) =
  1214 + if lstr_pgraph is
  1215 + {
  1216 + [] then (blines,spars),
  1217 + [h . t] then
  1218 + if h is
  1219 + {
  1220 + new_paragraph(txt) then //print("NP_t ["+txt+"]\n");
  1221 + if posw_transforming_text
  1222 + (split_string_into_lines(txt),build_bc,is_too_large,
  1223 + (String s) |-> text(s,empty),
  1224 + (String s) |-> new_paragraph(s),
  1225 + (String s) |-> to_continue(s)) is (bl,sp,bc,is_over) then
  1226 + //print("NB_t/bc=["+concat_bcont(bc)+"]\n");
  1227 + if is_over
  1228 + then (blines+bl,spars+sp+t)
  1229 + else posw_transforming_text(t,bc,is_too_large_i,is_too_large,blines+bl,spars+sp),
  1230 + to_continue(txt) then //print("TC_t ["+txt+"]\n");
  1231 + if posw_transforming_text
  1232 + (split_string_into_lines(txt),build_bc,is_too_large,
  1233 + (String s) |-> text(s,empty),
  1234 + (String s) |-> new_paragraph(s),
  1235 + (String s) |-> to_continue(s)) is (bl,sp,bc,is_over) then
  1236 + //print("TC_t/bc=["+concat_bcont(bc)+"]\n");
  1237 + if is_over
  1238 + then (blines+bl,spars+sp+t)
  1239 + else posw_transforming_text(t,bc,is_too_large_i,is_too_large,blines+bl,spars+sp),
  1240 + new_paragraph(lk,i) then //print("NP_l ["+txt(lk)+"]\n");
  1241 + if posw_transforming_text
  1242 + (split_string_into_lines(txt(lk)),build_bc,is_too_large,
  1243 + (String s) |-> link(s,action(lk),i,empty),
  1244 + (String s) |-> new_paragraph(link(s,action(lk)),i),
  1245 + (String s) |-> to_continue(link(s,action(lk)),i)) is (bl,sp,bc,is_over) then
  1246 + //print("NB_l/bc=["+concat_bcont(bc)+"]\n");
  1247 + if is_over
  1248 + then (blines+bl,spars+sp+t)
  1249 + else posw_transforming_text(t,bc,is_too_large_i,is_too_large,blines+bl,spars+sp),
  1250 + to_continue(lk,i) then //print("TC_l ["+txt(lk)+"]\n");
  1251 +// print("lt="+length(t)+"\n");
  1252 + if posw_transforming_text
  1253 + (split_string_into_lines(txt(lk)),build_bc,is_too_large,
  1254 + (String s) |-> link(s,action(lk),i,empty),
  1255 + (String s) |-> new_paragraph(link(s,action(lk)),i),
  1256 + (String s) |-> to_continue(link(s,action(lk)),i)) is (bl,sp,bc,is_over) then
  1257 + //print("TC_l/bc=["+concat_bcont(bc)+"]\n");
  1258 + if is_over
  1259 + then (blines+bl,spars+sp+t)
  1260 + else posw_transforming_text(t,bc,is_too_large_i,is_too_large,blines+bl,spars+sp),
  1261 + }
698 1262 }.
699 1263  
700 1264  
701   - *** (4.2.1.3) From a floating-widget
702   - ************************************
703 1265  
704   -define (Int32,String,String,List(String))
705   - transform_one_pgraph
  1266 + *** (4.2.1.4) From a floating-widget (against it)
  1267 + *************************************************
  1268 +
  1269 +
  1270 + Against a floating widget, the first line(s) of the text may be :
  1271 + . just the continuation of a paragrapg begun before;
  1272 + . the begining of a new paragraph
  1273 +
  1274 + And the last line of this text against the widget may the end of a paragraph, or just
  1275 + the middle of one (not necessary the same as the beginning, of course).
  1276 +
  1277 + To format this text, the function 'floatw_transforming_text' needs :
  1278 +
  1279 + . the no-formating initial text (a List(String) coming from the floatingw-widget
  1280 + itself),
  1281 + . a test for the available width,
  1282 + . a test for the available height
  1283 + . a List(BlockParagraph) under-construction that will take place agains thne widget,
  1284 + . a counter for the number of line of text to text the height,
  1285 + . a function to transform the string-line to a ParagraphLine : the initial value
  1286 + depends on the initial text received. If it is a continuation of a paragraph, the
  1287 + value is 'middle()', 'first()' either. Then, after a first use in the recursion,
  1288 + the value will be 'middle()'.
  1289 + . 2 functions to transform a List(ParagraphLine) into a BlockParagraph; as above, and
  1290 + for the same reasons, the initialization depends on the the initial text
  1291 + received. The first fonction is called 'cur_bp' - 'cur' is for current - because in
  1292 + the recursion its value will move to the second function whic is necessary
  1293 + 'to_continue'.
  1294 +
  1295 +
  1296 + #define (Int32,String,String,List(BlockLine))
  1297 + transform_to_one_pgraph
706 1298 (
707   - List(Int8) one_pgraph,
708   - Int32 i,
709   - String -> Bool is_too_large,
710   - Int32 -> Bool is_too_high,
711   - Int32 nb_line,
712   - String word,
713   - String line,
714   - List(String) against
  1299 + List(Int8) one_pgraph,
  1300 + String -> Bool is_too_large,
  1301 + Int32 -> Bool is_hight,
  1302 + String -> BlockLine to_bline,
  1303 + Int32 nb_line,
  1304 + String word,
  1305 + String line,
  1306 + List(BlockLine) against
715 1307 ) =
716 1308 if one_pgraph is
717 1309 {
718   - [] then
719   - (nb_line,word,line,against),
  1310 + [] then (nb_line,word,line,against),
720 1311 [c . t] then
721 1312 if c = ' '
722 1313 then with new_line = (String)(line+(if line = "" then "" else " ")+word),
723 1314 if is_too_large(new_line)
724   - then if is_too_high(nb_line+1)
725   - then
726   - /*
727   - print("word=["+word+"]\n");
728   - print("line=["+line+"]\n");
729   - print("t=["+implode(t)+"]\n");
730   - print_ls(against);
731   - print("----------------------------------------------------\n");
732   - */
733   - (nb_line,word+implode(t),line,against)
734   - else transform_one_pgraph
735   - (t,i+1,is_too_large,is_too_high,nb_line+1,"",word,[line . against])
736   - else transform_one_pgraph
737   - (t,i+1,is_too_large,is_too_high,nb_line,"",new_line,against)
738   - else transform_one_pgraph
739   - (t,i+1,is_too_large,is_too_high,nb_line,word+implode([c]),line,against)
  1315 + then if is_hight(nb_line)
  1316 + then // too large and enough hight :
  1317 + // -> stop the process
  1318 + // -> 'line' is transformed to BlockLine and added to the list
  1319 + // -> the rest of current text is added to word
  1320 + if t is []
  1321 + then (nb_line,word,"",[last(text(line,empty)) . against])
  1322 + else (nb_line,word+" "+implode(t),"",[to_bline(line) . against])
  1323 + else // too large but not enough hight :
  1324 + // -> 'line' is transformed to ParagraphLine and added to the list
  1325 + // -> 'word' became the begining of the next 'line'
  1326 + transform_to_one_pgraph
  1327 + (t,is_too_large,is_hight,(String s) |-> middle(text(s,empty)),
  1328 + nb_line+1,"",word,[to_bline(line) . against])
  1329 + else // not too large
  1330 + // -> no need to test the height
  1331 + // -> the future line against the widget is under construction
  1332 + transform_to_one_pgraph
  1333 + (t,is_too_large,is_hight,to_bline,nb_line,"",new_line,against)
  1334 + else transform_to_one_pgraph
  1335 + (t,is_too_large,is_hight,to_bline,nb_line,word+implode([c]),line,against)
  1336 + }.
  1337 +
  1338 +
  1339 +
  1340 +
  1341 +define (Int32,String,String,List(BlockLine))
  1342 + transform_to_one_pgraph
  1343 + (
  1344 + List(Int8) one_pgraph,
  1345 + BlockContent bc,
  1346 + String -> Bool is_too_large,
  1347 + Int32 -> Bool is_hight,
  1348 + (BlockContent,String) -> BlockLine to_bline,
  1349 + Int32 nb_line,
  1350 + String word,
  1351 + String line,
  1352 + List(BlockLine) against
  1353 + ) =
  1354 + if one_pgraph is
  1355 + {
  1356 + [] then (nb_line,word,line,against),
  1357 + [c . t] then
  1358 + if c = ' '
  1359 + then with new_line = (String)(line+(if line = "" then "" else " ")+word),
  1360 + if is_too_large(new_line+concat_bcont(bc))
  1361 + then if is_hight(nb_line)
  1362 + then // too large and enough hight :
  1363 + // -> stop the process
  1364 + // -> 'line' is transformed to BlockLine and added to the list
  1365 + // -> the rest of current text is added to word
  1366 + if t is []
  1367 + then (nb_line,word,"",[last(bc+text(line,empty)) . against])
  1368 + else (nb_line,word+" "+implode(t),"",[to_bline(bc,line) . against])
  1369 + else // too large but not enough hight :
  1370 + // -> 'line' is transformed to ParagraphLine and added to the list
  1371 + // -> 'word' became the begining of the next 'line'
  1372 + transform_to_one_pgraph
  1373 + (t,empty,is_too_large,is_hight,
  1374 + (BlockContent bc,String s) |-> middle(bc+text(s,empty)),
  1375 + nb_line+1,"",word,[to_bline(bc,line) . against])
  1376 + else // not too large
  1377 + // -> no need to test the height
  1378 + // -> the future line against the widget is under construction
  1379 + transform_to_one_pgraph
  1380 + (t,bc,is_too_large,is_hight,to_bline,nb_line,"",
  1381 + (if line ="" then " " else "")+new_line,
  1382 + against)
  1383 + else transform_to_one_pgraph
  1384 + (t,bc,is_too_large,is_hight,to_bline,nb_line,word+implode([c]),line,against)
  1385 + }.
  1386 +
  1387 + This function is called in the 'to_blocks()' function end used when then initial
  1388 + List(StringParagraph) is empty.
  1389 +
  1390 + The BlockContent came from the tranformation to make up the line between then
  1391 + float-widget. Hence, the recursive value is empty.
  1392 +
  1393 +define (List(BlockLine),List(StringParagraph))
  1394 + floatw_transforming_text
  1395 + (
  1396 + BlockContent bc,
  1397 + String -> Bool is_too_large,
  1398 + Int32 -> Bool is_hight
  1399 + ) =
  1400 + if bc is
  1401 + {
  1402 + empty then ([],[]),
  1403 + text(w,_) then
  1404 + if transform_to_one_pgraph
  1405 + (explode(w),empty,is_too_large,is_hight,
  1406 + (BlockContent b,String s) |-> middle(bc+text(s,empty)),
  1407 + 1,"","",[])
  1408 + is (new_nb_line,word,line,new_against) then
  1409 + // (Int32) new_nb_line = line counter
  1410 + // (String) word = . text not treated,
  1411 + // . or part of text after the widget, if line is empty
  1412 + // (String) line = line under construction. Empty means available height is
  1413 + // reached
  1414 + // (List(BlockLine)) new_against = will take place against the widget
  1415 + if line = ""
  1416 + then // end of the process
  1417 + (reverse(new_against),[to_continue(word)])
  1418 + else with new_line = (String)(line+" "+word),
  1419 + if is_too_large(new_line)
  1420 + then if is_hight(new_nb_line)
  1421 + then (reverse([middle(text(line,empty)) . new_against]),
  1422 + [to_continue(word)])
  1423 + else (reverse([middle(text(new_line,empty)) . new_against]),[])
  1424 + else (reverse([middle(text(new_line,empty)) . new_against]),[]),
  1425 +
  1426 + link(w,a,i,_) then
  1427 + if transform_to_one_pgraph
  1428 + (explode(w),empty,is_too_large,is_hight,
  1429 + (BlockContent b,String s) |-> middle(bc+link(s,a,i,empty)),
  1430 + 1,"","",[])
  1431 + is (new_nb_line,word,line,new_against) then
  1432 + // (Int32) new_nb_line = line counter
  1433 + // (String) word = . text not treated,
  1434 + // . or part of text after the widget, if line is empty
  1435 + // (String) line = line under construction. Empty means available height is
  1436 + // reached
  1437 + // (List(BlockLine)) new_against = will take place against the widget
  1438 + if line = ""
  1439 + then // end of the process
  1440 + (reverse(new_against),[to_continue(word)])
  1441 + else (reverse([middle(link(line,a,i,empty)) . new_against]),
  1442 + [to_continue(word)])
740 1443 }.
741 1444  
742   -define (List(List(String)),List(String))
  1445 +
  1446 + define (List(BlockLine),List(StringParagraph))
743 1447 floatw_transforming_text
744 1448 (
745   - List(String) pgraph, // liste de ยง
746   - String -> Bool is_too_large,
747   - Int32 -> Bool is_too_high,
748   - List(List(String)) against,
749   - Int32 nb_line // initialze = 0
  1449 + List(String) pgraph, // list (real) text paragraphs
  1450 + BlockContent bc,
  1451 + String -> Bool is_too_large_c,
  1452 + String -> Bool is_too_large,
  1453 + Int32 -> Bool is_hight,
  1454 + List(BlockLine) against,
  1455 + Int32 nb_line, // initialization = 1
  1456 + (BlockContent,String) -> BlockLine to_bline,
  1457 + (BlockContent,String) -> BlockLine to_middle,
  1458 + (BlockContent,String) -> BlockLine to_last,
  1459 + String -> BlockContent to_bcont
  1460 + ) =
  1461 + if pgraph is
  1462 + {
  1463 + [] then
  1464 + if floatw_transforming_text(bc,is_too_large_c,is_hight)
  1465 + is (new_against,new_str_pgraph)
  1466 + then (reverse(append(new_against,against)),new_str_pgraph),
  1467 + //(reverse(against),[])
  1468 + [h . t] then //print("h="+h+"\n");
  1469 + with new_bc = to_bcont(h),
  1470 + add_bc = bc+new_bc,
  1471 +//print("h=["+h+"]\n");
  1472 +//print("add_bc=["+concat_bcont(add_bc)+"]\n");
  1473 + if is_too_large_c(concat_bcont(add_bc))
  1474 + then (if transform_to_one_pgraph
  1475 + (explode(h),bc,is_too_large_c,is_hight,to_bline,nb_line,"","",[])
  1476 + is (new_nb_line,word,line,new_against) then
  1477 + // (Int32) new_nb_line = line counter
  1478 + // (String) word = . text not treated,
  1479 + // . or part of text after the widget, if line is empty
  1480 + // (String) line = line under construction. Empty means available height is
  1481 + // reached
  1482 + // (List(BlockLine)) new_against = will take place against the widget
  1483 +// print("line=["+line+"]\n");
  1484 +// print("word=["+word+"]\n");
  1485 + if line = ""
  1486 + then // end of the process
  1487 + (reverse(append(new_against, against)),[to_continue(word)])
  1488 + else // testing the result
  1489 + with new_line = (String)(line+" "+word),
  1490 + if is_too_large_c(new_line)
  1491 + then if is_hight(new_nb_line)
  1492 + then (against+reverse([to_middle(bc,line) . new_against]),
  1493 + [to_continue(word)])
  1494 + else floatw_transforming_text
  1495 + ([word]+t,empty,is_too_large,is_too_large,is_hight,
  1496 + append([to_middle(bc,line) . new_against],against),
  1497 + new_nb_line+1,to_middle,to_middle,to_last,to_bcont)
  1498 +
  1499 + else floatw_transforming_text
  1500 + (t,empty,is_too_large,is_too_large,is_hight,
  1501 + [to_middle(bc,new_line) . new_against]+against,
  1502 + new_nb_line+1,to_middle,to_middle,to_last,to_bcont))
  1503 +
  1504 + else if is_hight(nb_line)
  1505 + then with new_bl = (BlockLine)if t is [] then to_last(bc,h) else to_middle(bc,h),
  1506 + (reverse([new_bl . against]),[(StringParagraph)new_paragraph(concat(t))])
  1507 + else floatw_transforming_text
  1508 + (t,empty,is_too_large_c,is_too_large,is_hight,[to_bline(bc,h) . against],
  1509 + nb_line+1,to_middle,to_middle,to_last,to_bcont)
  1510 +
  1511 + }.
  1512 +
  1513 +
  1514 +
  1515 +
  1516 +define (List(BlockLine),BlockContent,List(String))
  1517 + floatw_transforming_text
  1518 + (
  1519 + List(String) pgraph,
  1520 + BlockContent bc,
  1521 + String -> Bool is_too_large_c,
  1522 + String -> Bool is_too_large,
  1523 + Int32 -> Bool is_hight,
  1524 + List(BlockLine) against,
  1525 + Int32 nb_line, // initialization = 1
  1526 + (BlockContent,String) -> BlockLine to_bline,
  1527 + (BlockContent,String) -> BlockLine to_middle,
  1528 + (BlockContent,String) -> BlockLine to_last,
  1529 + String -> BlockContent to_bcont,
  1530 + String -> BlockLine end_bl
  1531 + ) =
  1532 + if pgraph is
  1533 + {
  1534 + [] then (reverse(against),bc,[]),
  1535 + [h . t] then
  1536 + with new_bc = to_bcont(h),
  1537 + add_bc = bc+new_bc,
  1538 + if is_too_large_c(concat_bcont(add_bc))
  1539 + then (if transform_to_one_pgraph
  1540 + (explode(h),bc,is_too_large_c,is_hight,to_bline,nb_line,"","",[])
  1541 + is (new_nb_line,word,line,new_against) then
  1542 + // (Int32) new_nb_line = line counter
  1543 + // (String) word = . text not treated,
  1544 + // . or part of text after the widget, if line is empty
  1545 + // (String) line = line under construction. Empty means available height is
  1546 + // reached
  1547 + // (List(BlockLine)) new_against = will take place against the widget
  1548 + if line = ""
  1549 + then // end of the process
  1550 + (reverse(append(new_against, against)),empty,[word])
  1551 + else // testing the result
  1552 + with new_line = (String)(line+" "+word),
  1553 + if is_too_large_c(new_line)
  1554 + then if is_hight(new_nb_line)
  1555 + then (against+reverse([to_middle(bc,line) . new_against]),
  1556 + empty,[word])
  1557 + else floatw_transforming_text
  1558 + ([word]+t,empty,is_too_large,is_too_large,is_hight,
  1559 + append([to_middle(bc,line) . new_against],against),
  1560 + new_nb_line+1,to_middle,to_middle,to_last,to_bcont,end_bl)
  1561 +
  1562 + else floatw_transforming_text
  1563 + (t,empty,is_too_large,is_too_large,is_hight,
  1564 + [end_bl(new_line) . new_against]+against,
  1565 + new_nb_line+1,to_middle,to_middle,to_last,to_bcont,end_bl))
  1566 +
  1567 + else if is_hight(nb_line)
  1568 + then with new_bl = (BlockLine)if t is [] then to_last(bc,h) else to_middle(bc,h),
  1569 + (reverse([new_bl . against]),empty,t)
  1570 + else floatw_transforming_text
  1571 + (t,add_bc,is_too_large_c,is_too_large,is_hight,against,
  1572 + nb_line+1,to_middle,to_middle,to_last,to_bcont,end_bl)
  1573 +
  1574 + }.
  1575 +
  1576 +
  1577 +
  1578 +
  1579 +
  1580 +
  1581 +
  1582 + #define (List(BlockLine),List(StringParagraph))
  1583 + floatw_transforming_text
  1584 + (
  1585 + List(String) pgraph, // list (real) text paragraphs
  1586 + BlockContent bc,
  1587 + String -> Bool is_too_large_c,
  1588 + String -> Bool is_too_large,
  1589 + Int32 -> Bool is_hight,
  1590 + List(BlockLine) against,
  1591 + Int32 nb_line, // initialization = 1
  1592 + (BlockContent,String) -> BlockLine to_bline,
  1593 + (BlockContent,String) -> BlockLine to_middle,
  1594 + (BlockContent,String) -> BlockLine to_last
750 1595 ) =
751 1596 if pgraph is
752 1597 {
753 1598 [] then (reverse(against),[]),
754 1599 [h . t] then
755   - //print("h=["+h+"]\n");
756   - if is_too_large(h)
757   - then (if transform_one_pgraph(explode(h),0,is_too_large,is_too_high,nb_line,"","",[])
  1600 + with new_bc = to_bcont(h),
  1601 + add_bc = bc+new_bc,
  1602 + if is_too_large_c(concat_bcont(add_bc))
  1603 + then (if transform_to_one_pgraph
  1604 + (explode(h),is_too_large_c,is_hight,to_bline,nb_line,"","",[])
758 1605 is (new_nb_line,word,line,new_against) then
759   - (with new_line = (String)(line+" "+word),
760   - if is_too_large(new_line)
761   - then if is_too_high(new_nb_line+1)
762   - then
763   - //print("new_against : \n");print_ls(new_against);
764   -
765   - (against+[reverse(new_against)],[new_line])
766   - else //(reverse([line . new_against]+against),[word]+pgraph)
767   - floatw_transforming_text
768   - ([word]+t,is_too_large,is_too_high,
769   - [[line . new_against] . against],new_nb_line+1)
770   -
771   - else if is_too_high(new_nb_line+1)
772   - then ([reverse([line . new_against]). against],[word])
773   - else //(reverse([new_line . new_against]+against),pgraph),
774   - floatw_transforming_text
775   - (t,is_too_large,is_too_high,
776   - [reverse([new_line . new_against]) . against],new_nb_line+1)))
777   -
778   - else print("not_too_large \n");
779   - with new_against = (List(List(String)))[[h] . against],
780   - if is_too_high(nb_line+1)
781   - then (reverse(against),pgraph)
  1606 + // (Int32) new_nb_line = line counter
  1607 + // (String) word = . text not treated,
  1608 + // . or part of text after the widget, if line is empty
  1609 + // (String) line = line under construction. Empty means available height is
  1610 + // reached
  1611 + // (List(BlockLine)) new_against = will take place against the widget
  1612 + if line = ""
  1613 + then // end of the process
  1614 + (reverse(append(new_against, against)),[to_continue(word)])
  1615 + else // testing the result
  1616 + with new_line = (String)(line+" "+word),
  1617 + if is_too_large_c(new_line)
  1618 + then if is_hight(new_nb_line)
  1619 + then (against+reverse([to_middle(line) . new_against]),
  1620 + [to_continue(word)])
  1621 + else floatw_transforming_text
  1622 + ([word]+t,is_too_large,is_too_large,is_hight,
  1623 + append([to_middle(line) . new_against],against),
  1624 + new_nb_line+1,to_middle,to_middle,to_last)
  1625 +
  1626 + else floatw_transforming_text
  1627 + (t,is_too_large,is_too_large,is_hight,
  1628 + [to_middle(new_line) . new_against]+against,
  1629 + new_nb_line+1,to_middle,to_middle,to_last))
  1630 +
  1631 + else if is_hight(nb_line)
  1632 + then with new_bl = (BlockLine)if t is [] then to_last(h) else to_middle(h),
  1633 + (reverse([new_bl . against]),[(StringParagraph)new_paragraph(concat(t))])
782 1634 else floatw_transforming_text
783   - (t,is_too_large,is_too_high,new_against,nb_line+1)
  1635 + (t,is_too_large_c,is_too_large,is_hight,[to_bline(h) . against],
  1636 + nb_line+1,to_middle,to_middle,to_last)
784 1637  
785   - }.
  1638 + }.
786 1639  
787   -define (List(List(String)),String)
  1640 +
  1641 +
  1642 +define (List(BlockLine),List(StringParagraph))
788 1643 floatw_transforming_text
789 1644 (
790   - String text,
791   - String -> Bool is_too_large,
792   - Int32 -> Bool is_too_high
  1645 + List(StringParagraph) lstr_pgraph,
  1646 + BlockContent build_bc,
  1647 + String -> Bool is_too_large_i,
  1648 + String -> Bool is_too_large,
  1649 + Int32 -> Bool is_hight,
  1650 + List(BlockLine) blines,
  1651 + List(StringParagraph) spars
793 1652 ) =
794   - if floatw_transforming_text
795   - (split_string_into_lines(text),
796   - is_too_large,is_too_high,
797   - (List(List(String)))[],0) is (against,after) then (against,concat(after)).
  1653 + if lstr_pgraph is
  1654 + {
  1655 + [] then (blines,spars),
  1656 + [h . t] then
  1657 + if h is
  1658 + {
  1659 + new_paragraph(txt) then
  1660 + print("NP-t=["+txt+"]\n");
  1661 + /*
  1662 + print("---------------\n");
  1663 + print_ls(split_string_into_lines(txt));
  1664 + print("---------------\n");
  1665 + */
  1666 + if floatw_transforming_text
  1667 + (split_string_into_lines(txt),build_bc,is_too_large_i,is_too_large,is_hight,
  1668 + (List(BlockLine))[],1,
  1669 + (BlockContent bc,String s) |-> (BlockLine)first(bc+text(s,empty)),
  1670 + (BlockContent bc,String s) |-> (BlockLine)middle(bc+text(s,empty)),
  1671 + (BlockContent bc,String s) |-> (BlockLine)last(bc+text(s,empty)),
  1672 + (String s) |-> text(s,empty),
  1673 + (String s) |-> (BlockLine)last(text(s,empty))) is (lbl,new_bc,more_txt)
  1674 + then
  1675 + if new_bc is empty
  1676 + then (blines+lbl,[(StringParagraph)new_paragraph(concat(more_txt)) . t])
  1677 + else floatw_transforming_text
  1678 + (t,new_bc,is_too_large_i,is_too_large,is_hight,blines+lbl,spars),
  1679 + /*
  1680 + then floatw_transforming_text(
  1681 + t,build_bc,is_too_large_i,is_too_large,is_hight,blines+bl,spars+sp),
  1682 + */
  1683 + to_continue(txt) then
  1684 + print("TC-t=["+txt+"]\n");
  1685 + if floatw_transforming_text
  1686 + (split_string_into_lines(txt),build_bc,is_too_large,is_too_large,is_hight,
  1687 + (List(BlockLine))[],1,
  1688 + (BlockContent bc,String s) |-> (BlockLine)middle(bc+text(s,empty)),
  1689 + (BlockContent bc,String s) |-> (BlockLine)middle(bc+text(s,empty)),
  1690 + (BlockContent bc,String s) |-> (BlockLine)last(bc+text(s,empty)),
  1691 + (String s) |-> text(s,empty),
  1692 + (String s) |-> (BlockLine)last(text(s,empty))) is (lbl,new_bc,more_txt)
  1693 + then
  1694 + if new_bc is empty
  1695 + then (blines+lbl,[(StringParagraph)to_continue(concat(more_txt)) . t])
  1696 + else floatw_transforming_text
  1697 + (t,new_bc,is_too_large_i,is_too_large,is_hight,blines+lbl,spars),
  1698 + /*
  1699 + then floatw_transforming_text
  1700 + (t,build_bc,is_too_large_i,is_too_large,is_hight,blines+bl,spars+sp),
  1701 + */
  1702 + new_paragraph(lk,i) then
  1703 + print("NB-l=["+txt(lk)+"]\n");
  1704 + if floatw_transforming_text
  1705 + (split_string_into_lines(txt(lk)), build_bc,is_too_large_i,is_too_large,is_hight,
  1706 + (List(BlockLine))[],1,
  1707 + (BlockContent bc,String s) |-> (BlockLine)first(bc+link(s,action(lk),i,empty)),
  1708 + (BlockContent bc,String s) |-> (BlockLine)middle(bc+link(s,action(lk),i,empty)),
  1709 + (BlockContent bc,String s) |-> (BlockLine)last(bc+link(s,action(lk),i,empty)),
  1710 + (String s) |-> link(s,action(lk),i,empty),
  1711 + (String s) |-> (BlockLine)last(link(s,action(lk),i,empty)))
  1712 + is (lbl,new_bc,more_txt) //(bl,sp)
  1713 + then
  1714 + if new_bc is empty
  1715 + then (blines+lbl,
  1716 + [(StringParagraph)new_paragraph(link(concat(more_txt),action(lk)),i) . t])
  1717 + else floatw_transforming_text
  1718 + (t,new_bc,is_too_large_i,is_too_large,is_hight,blines+lbl,spars),
  1719 + /*
  1720 + then floatw_transforming_text
  1721 + (t,build_bc,is_too_large_i,is_too_large,is_hight,blines+lbl,spars+sp),
  1722 + */
  1723 + to_continue(lk,i) then
  1724 + print("TC-l=["+txt(lk)+"]\n");
  1725 + if floatw_transforming_text
  1726 + (split_string_into_lines(txt(lk)),build_bc,is_too_large,is_too_large,is_hight,
  1727 + (List(BlockLine))[],1,
  1728 + (BlockContent bc,String s) |-> (BlockLine)middle(bc+link(s,action(lk),i,empty)),
  1729 + (BlockContent bc,String s) |-> (BlockLine)middle(bc+link(s,action(lk),i,empty)),
  1730 + (BlockContent bc,String s) |-> (BlockLine)last(bc+link(s,action(lk),i,empty)),
  1731 + (String s) |-> link(s,action(lk),i,empty),
  1732 + (String s) |-> (BlockLine)last(link(s,action(lk),i,empty)))
  1733 + is (lbl,new_bc,more_txt)
  1734 + then
  1735 + if new_bc is empty
  1736 + then (blines+lbl,
  1737 + [(StringParagraph)to_continue(link(concat(more_txt),action(lk)),i) . t])
  1738 + else floatw_transforming_text
  1739 + (t,new_bc,is_too_large_i,is_too_large,is_hight,blines+lbl,spars),
  1740 + /*
  1741 + then floatw_transforming_text
  1742 + (t,build_bc,is_too_large_i,is_too_large,is_hight,blines+bl,spars+sp),
  1743 + */
  1744 + }
  1745 + }.
  1746 +
  1747 +
  1748 +define (List(BlockLine),List(StringParagraph))
  1749 + floatw_transforming_text_0
  1750 + (
  1751 + List(StringParagraph) lstr_pgraph,
  1752 + BlockContent build_bc,
  1753 + String -> Bool is_too_large_i,
  1754 + String -> Bool is_too_large,
  1755 + Int32 -> Bool is_hight,
  1756 + List(BlockLine) blines,
  1757 + List(StringParagraph) spars
  1758 + ) =
  1759 + if lstr_pgraph is []
  1760 + then print("GO\n"); floatw_transforming_text(build_bc,is_too_large,is_hight)
  1761 + else //print("LP="+length(lstr_pgraph)+"\n");
  1762 + floatw_transforming_text(lstr_pgraph,build_bc,is_too_large_i,is_too_large,is_hight,[],[]).
  1763 +
798 1764  
799 1765  
800   - *** (4.2.) Basic function
801   - *************************
  1766 +
  1767 + *** (4.2.2) Basic function
  1768 + **************************
802 1769  
803 1770 define List(Block)
804 1771 to_blocks
... ... @@ -809,11 +1776,16 @@ define List(Block)
809 1776 Int32 indent,
810 1777 Int32 height_writing,
811 1778 (String,Int32) -> Bool is_too_large,
812   - String so_far,
  1779 + List(StringParagraph) so_far,
813 1780 Maybe((Widget,LR_Widget,Int32,Int32,
814   - (String,String -> Bool)
815   - -> (List(List(String)),String)) ) mb_wid,
816   - List(Block) blocks
  1781 + (List(StringParagraph),
  1782 + BlockContent,
  1783 + String -> Bool,
  1784 + String -> Bool,
  1785 + List(BlockLine),List(StringParagraph))
  1786 + -> (List(BlockLine),List(StringParagraph))) ) mb_wid,
  1787 + List(Block) blocks,
  1788 + Int32 link_index
817 1789 ) =
818 1790 if content is
819 1791 {
... ... @@ -822,18 +1794,21 @@ define List(Block)
822 1794 {
823 1795 failure then
824 1796 reverse([t_block(transforming_text
825   - (so_far,
  1797 + (reverse(so_far),
826 1798 (String s) |-> is_too_large(s,htc_width-indent),
827 1799 (String s) |-> is_too_large(s,htc_width))) . blocks])
828 1800 success(wxy) then
829 1801 if wxy is (wid,lr,yp,sp,transform) then
830 1802 if get_size(wid)(unique) is (wid_width,h_wid) then
831   - if transform(so_far,
832   - (String s) |-> is_too_large(s,htc_width-wid_width-sp))
  1803 + //print("lsofar="+length(so_far)+"\n");
  1804 + if transform(reverse(so_far),empty,
  1805 + (String s) |-> is_too_large(s,htc_width-indent-wid_width-sp),
  1806 + (String s) |-> is_too_large(s,htc_width-wid_width-sp),
  1807 + [],[])
833 1808 is (against_widget,more_text) then
834 1809 reverse(blocks)
835 1810 +[wt_block(against_widget,lr,yp,sp,wid)
836   - . if more_text = ""
  1811 + . if more_text is []
837 1812 then []
838 1813 else [t_block(transforming_text
839 1814 (more_text,
... ... @@ -841,52 +1816,73 @@ define List(Block)
841 1816 (String s) |-> is_too_large(s,htc_width)))]]
842 1817 },
843 1818 string(s,htc) then
844   - to_blocks(htc,htc_width,margin,indent,height_writing,is_too_large,so_far+s,mb_wid,blocks),
  1819 + //print("s=["+s+"]\n");
  1820 + to_blocks(htc,htc_width,margin,indent,height_writing,is_too_large,
  1821 + add(so_far,s),mb_wid,blocks,link_index),
845 1822 linkw(lw,htc) then
846   - to_blocks(htc,htc_width,margin,indent,height_writing,is_too_large,so_far,mb_wid,blocks),
  1823 + to_blocks(htc,htc_width,margin,indent,height_writing,is_too_large,
  1824 + add(so_far,lw,link_index),mb_wid,blocks,link_index+1),
847 1825 posw(pw,htc) then
848 1826 if pw is
849 1827 {
850   - left_pos(vp,sp,wid) then
851   - to_blocks(htc,htc_width,margin,indent,height_writing,is_too_large,"",
  1828 + left_pw(vp,sp,wid) then
  1829 + to_blocks(htc,htc_width,margin,indent,height_writing,is_too_large,[],
852 1830 success((wid,left,vp,sp,posw_transforming_text)),
853 1831 reverse([t_block(transforming_text
854   - (so_far,
  1832 + (reverse(so_far),
855 1833 (String s) |-> is_too_large(s,htc_width-indent),
856   - (String s) |-> is_too_large(s,htc_width))) . blocks])),
857   - right_pos(vp,sp,wid) then
858   - to_blocks(htc,htc_width,margin,indent,height_writing,is_too_large,"",
  1834 + (String s) |-> is_too_large(s,htc_width))) . blocks]),
  1835 + link_index),
  1836 + right_pw(vp,sp,wid) then
  1837 + to_blocks(htc,htc_width,margin,indent,height_writing,is_too_large,[],
859 1838 success((wid,right,vp,sp,posw_transforming_text)),
860 1839 reverse([t_block(transforming_text
861   - (so_far,
  1840 + (reverse(so_far),
862 1841 (String s) |-> is_too_large(s,htc_width-indent),
863   - (String s) |-> is_too_large(s,htc_width))) . blocks])),
  1842 + (String s) |-> is_too_large(s,htc_width))) . blocks]),
  1843 + link_index),
864 1844 },
865 1845 floatingw(fw,htc) then
866 1846 if fw is
867 1847 {
868   - left(sp,wid) then
  1848 + left_fw(sp,wid) then
869 1849 if get_size(wid)(unique) is (_,wid_height) then
870   - to_blocks(htc,htc_width,margin,indent,height_writing,is_too_large,"",
  1850 + if transforming_text_before_fw
  1851 + (reverse(so_far),htc,
  1852 + (String s) |-> is_too_large(s,htc_width-indent),
  1853 + (String s) |-> is_too_large(s,htc_width))
  1854 + is (new_blocks,new_htc,new_str_p,nb_lk) then
  1855 + to_blocks(new_htc,htc_width,margin,indent,height_writing,is_too_large,new_str_p,
871 1856 success((wid,left,0,sp,
872   - (String s,String -> Bool stl) |->
873   - floatw_transforming_text
874   - (s,stl,(Int32 n) |-> (n*height_writing)>wid_height))),
875   - reverse([t_block(transforming_text
876   - (so_far,
877   - (String s) |-> is_too_large(s,htc_width-indent),
878   - (String s) |-> is_too_large(s,htc_width))) . blocks])),
879   - right(sp,wid) then
  1857 + (List(StringParagraph) s,
  1858 + BlockContent _,
  1859 + String -> Bool stli,
  1860 + String -> Bool stl,
  1861 + List(BlockLine) lbl,List(StringParagraph)lsp) |->
  1862 + floatw_transforming_text_0
  1863 + (s,empty,stli,stl,
  1864 + (Int32 n) |-> n = 1+(wid_height/height_writing),[],[]))),
  1865 + reverse([t_block(new_blocks) . blocks]),
  1866 + link_index+nb_lk),
  1867 + right_fw(sp,wid) then
880 1868 if get_size(wid)(unique) is (_,wid_height) then
881   - to_blocks(htc,htc_width,margin,indent,height_writing,is_too_large,"",
  1869 + if transforming_text_before_fw
  1870 + (reverse(so_far),htc,
  1871 + (String s) |-> is_too_large(s,htc_width-indent),
  1872 + (String s) |-> is_too_large(s,htc_width))
  1873 + is (new_blocks,new_htc,new_str_p,nb_lk) then
  1874 + to_blocks(new_htc,htc_width,margin,indent,height_writing,is_too_large,new_str_p,
882 1875 success((wid,right,0,sp,
883   - (String s,String -> Bool stl) |->
884   - floatw_transforming_text
885   - (s,stl,(Int32 n) |-> (n*height_writing)>wid_height))),
886   - reverse([t_block(transforming_text
887   - (so_far,
888   - (String s) |-> is_too_large(s,htc_width-indent),
889   - (String s) |-> is_too_large(s,htc_width))) . blocks])),
  1876 + (List(StringParagraph) s,
  1877 + BlockContent bc,
  1878 + String -> Bool stli,
  1879 + String -> Bool stl,
  1880 + List(BlockLine) lbl,List(StringParagraph)lsp) |->
  1881 + floatw_transforming_text_0
  1882 + (s,empty,stli,stl,
  1883 + (Int32 n) |-> n=1+(wid_height/height_writing),[],[]))),
  1884 + reverse([t_block(new_blocks) . blocks]),
  1885 + link_index+nb_lk),
890 1886 }
891 1887 }.
892 1888  
... ... @@ -900,7 +1896,8 @@ define List(Block)
900 1896 Int32 height_writing,
901 1897 (String,Int32) -> Bool is_too_large
902 1898 ) =
903   - to_blocks(content,htc_width,margin,indent,height_writing,is_too_large,"",failure,[]).
  1899 + to_blocks(content,htc_width,margin,indent,height_writing,is_too_large,
  1900 + [],failure,[],0).
904 1901  
905 1902  
906 1903  
... ... @@ -910,16 +1907,11 @@ define List(Block)
910 1907 define Int32
911 1908 pgraph_height
912 1909 (
913   - List(List(String)) lls,
914   - Int32 total_font_height,
915   - Int32 v_space
  1910 + List(BlockLine) lbp,
  1911 + Int32 total_font_height,
  1912 + Int32 v_space
916 1913 ) =
917   - if lls is
918   - {
919   - [] then 0,
920   - [h . t] then
921   - (length(h) * (total_font_height+v_space)) + pgraph_height(t,total_font_height,v_space)
922   - }.
  1914 + length(lbp) * (total_font_height+v_space).
923 1915  
924 1916 define Int32
925 1917 height
... ... @@ -935,7 +1927,9 @@ define Int32
935 1927 if h is
936 1928 {
937 1929 t_block(pgraph) then pgraph_height(pgraph,total_font_height,v_space),
938   - wt_block(_,_,_,sp,wid) then if get_size(wid)(unique) is (w,h) then h+sp+v_space
  1930 + wt_block(pgraph,_,_,sp,wid) then //if get_size(wid)(unique) is (w,h) then h+v_space
  1931 + max(if get_size(wid)(unique) is (w,h) then h+v_space,
  1932 + pgraph_height(pgraph,total_font_height,v_space))
939 1933 }+height(t,total_font_height,v_space)
940 1934 }.
941 1935  
... ... @@ -944,14 +1938,23 @@ define Int32
944 1938 *** (6) Draw the hypertext
945 1939 **************************
946 1940  
  1941 +
947 1942 *** (6.1) Justify a text
948 1943 ************************
949 1944  
950 1945 The purpose is to print a string onto the left border AND onto the right border by
951   - adding spaces between words. Steps to achieve it are (here space is the character ' '):
952   - . determining the number of spaces in the string (nb_spaces);
953   - . computing the total number of spaces to add (add_spaces);
954   - . adding (add_spaces/nb_spaces) spaces at the originel one between to words.
  1946 + adding spaces between words.
  1947 +
  1948 + Steps to achieve it are (here space is the character ' '):
  1949 + . determining the number of locations where spaces are required : this number is just
  1950 + the number of words in the line, less on (locations_nb)
  1951 +
  1952 + . computing the sum of pixels used by spaces (spaces_sum)
  1953 +
  1954 + . computing the minimum of spaces to put between words (mini_space)
  1955 +
  1956 + adding (add_spaces/nb_spaces) spaces at the originel one between to
  1957 + words.
955 1958  
956 1959 But, as (add_spaces (mod nb_spaces)) may be greater than 0, one more space will be
957 1960 added to spaces which are on the left and on the right of the medium space of the all
... ... @@ -961,115 +1964,280 @@ define Int32
961 1964 First, extract the words one a text line : the number of spaces will be the number of
962 1965 words minus 1.
963 1966  
964   -define String
  1967 +
  1968 +
  1969 +define (String,Int32)
965 1970 justify_text
966 1971 (
967 1972 List(String) words,
968 1973 String spaces,
969 1974 Int32 -> String one_more,
  1975 + String so_far,
970 1976 Int32 n
971 1977 ) =
972 1978 if words is
973 1979 {
974   - [] then "",
  1980 + [] then (so_far,n),
975 1981 [h . t] then
976 1982 if t is []
977   - then h
978   - else justify_text(t,spaces,one_more,n+1)+spaces+one_more(n)+h
  1983 + then (h+so_far,n)
  1984 + else justify_text(t,spaces,one_more,spaces+one_more(n)+h+so_far,n+1)
979 1985 }.
980 1986  
  1987 +define BlockContent
  1988 + justify_text
  1989 + (
  1990 + BlockContent content,
  1991 + String spaces,
  1992 + Int32 -> String one_more,
  1993 + Int32 n
  1994 + ) =
  1995 + if content is
  1996 + {
  1997 + empty then empty,
  1998 + text(s,bc) then
  1999 + if justify_text(extract_words(s),spaces,one_more,"",n) is (new_s,new_n)
  2000 + then //print_ls(extract_words(s));
  2001 + //print("s=["+s+"]\n");
  2002 + text(new_s,justify_text(bc,spaces,one_more,new_n))
  2003 + link(s,a,i,bc) then
  2004 + if justify_text(extract_words(s),spaces,one_more,"",n) is (new_s,new_n)
  2005 + then //print_ls(extract_words(s));
  2006 + //print("s=["+s+"]\n");
  2007 + link(new_s,a,i,justify_text(bc,spaces,one_more,new_n))
  2008 + }.
981 2009  
982   -define String
  2010 +
  2011 +define BlockContent
983 2012 justify_text
984 2013 (
985   - String text,
  2014 + BlockContent bc,
986 2015 Int32 width,
987 2016 String -> Int32 string_width
988 2017 ) =
989   - with words = extract_words(text),
990   - nb_spaces = length(words)-1,
991   - w_space = string_width(" "),
992   - add_spaces = max(0,(width-string_width(concat(words)))/w_space),
993   - justify_text
994   - (words,
995   - constant_string(max(1,add_spaces/nb_spaces),' '),
996   - with q = (add_spaces (mod nb_spaces)),
  2018 + with text = concat_bcont(bc),
  2019 + words = extract_words(text),
  2020 + locations_nb = length(words)-1,
  2021 + w_space = string_width(" "),
  2022 + //spaces_to_add = max(1,(width-string_width(concat(words)))/w_space),
  2023 + spaces_to_add = (Int32)((width-string_width(concat(words)))/w_space),
  2024 + with jt =
  2025 + justify_text(bc,
  2026 + constant_string(max(1,spaces_to_add/locations_nb),' '), // at least, between two words
  2027 + with q = (spaces_to_add (mod locations_nb)), // spaces to distribute no-equally
997 2028 (Int32 ct) |->
998 2029 if q = 0 then ""
999   - else with l = (nb_spaces/2)-(q/2),
1000   - r = (nb_spaces/2)+(q/2)+(q (mod 2)),
1001   - if l=<ct & ct=<r then " " else "",
1002   - 0).
  2030 + else with l = (locations_nb/2)-(q/2),
  2031 + r = (locations_nb/2)+(q/2)+(q (mod 2)),
  2032 + if l<ct & ct=<r then " " else "",
  2033 + 0),
  2034 + //print("JT=["+concat_bcont(jt)+"]\n");
  2035 + //print("JT="+string_width(jt)+" W="+width+" ["+jt+"]\n");
  2036 + jt.
  2037 +
  2038 +
  2039 +
  2040 +
  2041 + *** (6.2) Drawing tools
  2042 + ***********************
  2043 +
  2044 + Those tools are common with the handler.
1003 2045  
1004 2046  
  2047 + *** (6.2.1) Compute margin
  2048 + **************************
  2049 +
  2050 +define Int32
  2051 + compute_margin
  2052 + (
  2053 + HyperTextParameters parms,
  2054 + String s,
  2055 + Int32 width,
  2056 + Int32 with_indent // 1 if with indent, 0 if not
  2057 + ) =
  2058 + if justify(parms) is
  2059 + {
  2060 + center then margin(parms)+(width-string_width(parms)(s))/2, // no indent when center
  2061 + left then margin(parms)+(indent(parms)*with_indent),
  2062 + right then margin(parms)+width-string_width(parms)(s),
  2063 + both then margin(parms)+(indent(parms)*with_indent)
  2064 + }.
  2065 +
  2066 +
  2067 +
  2068 + *** (6.2.2) Formating the block-content to print
  2069 + ************************************************
  2070 +
1005 2071  
1006   - *** (6.2) Draw a text
  2072 +define BlockContent
  2073 + block_content_format
  2074 + (
  2075 + HyperTextParameters parms,
  2076 + BlockContent bc,
  2077 + Int32 width
  2078 + ) =
  2079 + if bc is
  2080 + {
  2081 + empty then empty
  2082 + text(s,_) then if justify(parms) is
  2083 + {
  2084 + center then bc,
  2085 + left then bc,
  2086 + right then bc,
  2087 + both then justify_text(bc,width,string_width(parms))
  2088 + },
  2089 + link(s,a,i,_) then if justify(parms) is
  2090 + {
  2091 + center then bc,
  2092 + left then bc,
  2093 + right then bc,
  2094 + both then justify_text(bc,width,string_width(parms))
  2095 + },
  2096 + }.
  2097 +
  2098 +
  2099 + *** (6.3) Draw a text
1007 2100 *********************
1008 2101  
  2102 +define RGB -> RGB
  2103 + text_color
  2104 + (
  2105 + BlockContent bc,
  2106 + RGB lk_color
  2107 + ) =
  2108 + (RGB rgb) |->
  2109 + if bc is
  2110 + {
  2111 + empty then rgb,
  2112 + text(_,_) then rgb,
  2113 + link(_,_,_,_) then lk_color
  2114 + }.
1009 2115  
1010 2116 define Int32
1011 2117 draw_text
1012 2118 (
1013   - WidgetDrawToolBox dtb,
1014   - HyperTextParameters parms,
1015   - List(String) text,
1016   - String -> Int32 c_x_pos, // current x_pos
1017   - String -> Int32 x_pos,
1018   - Int32 y_pos,
1019   - (List(String),String) -> String print_text
  2119 + WidgetDrawToolBox dtb,
  2120 + HyperTextParameters parms,
  2121 + String text,
  2122 + RGB -> RGB text_color,
  2123 + Int32 x_pos,
  2124 + Int32 y_pos
  2125 + ) = //print("T=["+text+"]\n");
  2126 + if effect(parms) is
  2127 + {
  2128 + normal(color) then
  2129 + draw(dtb)(text,font(parms),text_color(color),position(x_pos,y_pos)),
  2130 + shadow(mc,sc,dx,dy) then
  2131 + with xp = x_pos,
  2132 + forget(draw(dtb)(text,font(parms),sc,position(xp+dx,y_pos+dy)));
  2133 + draw(dtb)(text,font(parms),mc,position(xp,y_pos)),
  2134 + engraved(color) then
  2135 + with xp = x_pos,
  2136 + col = text_color(color),
  2137 + forget(draw(dtb)(text,font(parms),lighten(col),position(xp+2,y_pos+2)));
  2138 + forget(draw(dtb)(text,font(parms),darken(col),position(xp,y_pos)));
  2139 + draw(dtb)(text,font(parms),col,position(xp+1,y_pos+1)),
  2140 + relief(color) then
  2141 + with xp = x_pos,
  2142 + col = text_color(color),
  2143 + forget(draw(dtb)(text,font(parms),darken(col),position(xp+2,y_pos+2)));
  2144 + forget(draw(dtb)(text,font(parms),lighten(col),position(xp,y_pos)));
  2145 + draw(dtb)(text,font(parms),col,position(xp+1,y_pos+1))
  2146 + }.
  2147 +
  2148 +define Int32
  2149 + nb_first_spaces
  2150 + (
  2151 + List(Int8) l
1020 2152 ) =
1021   - if text is
  2153 + if l is
1022 2154 {
1023   - [] then y_pos,
1024   - [h . t] then //print("["+h+"]\n");
1025   - if effect(parms) is
1026   - {
1027   - normal(color) then
1028   - forget(draw(dtb)(print_text(t,h),font(parms),color,position(c_x_pos(h),y_pos))),
1029   - shadow(mc,sc,dx,dy) then
1030   - with xp = c_x_pos(h),
1031   - pt = print_text(t,h),
1032   - forget(draw(dtb)(pt,font(parms),sc,position(xp+dx,y_pos+dy)));
1033   - forget(draw(dtb)(pt,font(parms),mc,position(xp,y_pos))),
1034   - engraved(color) then
1035   - with xp = c_x_pos(h),
1036   - pt = print_text(t,h),
1037   - forget(draw(dtb)(pt,font(parms),lighten(color),position(xp+2,y_pos+2)));
1038   - forget(draw(dtb)(pt,font(parms),darken(color),position(xp,y_pos)));
1039   - forget(draw(dtb)(pt,font(parms),color,position(xp+1,y_pos+1))),
1040   - relief(color) then
1041   - with xp = c_x_pos(h),
1042   - pt = print_text(t,h),
1043   - forget(draw(dtb)(pt,font(parms),darken(color),position(xp+2,y_pos+2)));
1044   - forget(draw(dtb)(pt,font(parms),lighten(color),position(xp,y_pos)));
1045   - forget(draw(dtb)(pt,font(parms),color,position(xp+1,y_pos+1)))
1046   - };
1047   - draw_text(dtb,parms,t,x_pos,x_pos,y_pos+total_font_height(parms)+v_space(parms),print_text)
  2155 + [] then 0,
  2156 + [h . t] then
  2157 + if h = ' ' then 1+nb_first_spaces(t)
  2158 + else 0
1048 2159 }.
1049 2160  
  2161 +define One
  2162 + draw_text
  2163 + (
  2164 + WidgetDrawToolBox dtb,
  2165 + HyperTextParameters parms,
  2166 + BlockContent content,
  2167 + RGB -> RGB text_colo,
  2168 + Int32 x_pos,
  2169 + Int32 y_pos
  2170 + ) = //print("T=["+text+"]\n");
  2171 + if content is
  2172 + {
  2173 + empty then unique,
  2174 + text(s,bc) then
  2175 + draw_text(dtb,parms,bc,text_colo,
  2176 + x_pos+draw_text(dtb,parms,s,text_color(content,link_color(parms)),x_pos,y_pos),
  2177 + y_pos),
  2178 + link(s,_,_,bc) then
  2179 + with new_x_pos = x_pos+draw_text(dtb,parms,s,text_color(content,link_color(parms)),x_pos,y_pos),
  2180 + draw(dtb)(rect(x_pos+string_width(parms)(constant_string(nb_first_spaces(explode(s)),' ')),
  2181 + y_pos+1,new_x_pos,y_pos+2),link_color(parms));
  2182 + draw_text(dtb,parms,bc,text_colo,new_x_pos,y_pos)
  2183 + }.
  2184 +
  2185 +
  2186 +
  2187 + What is the value of y_pos ?
  2188 + ----------------------------
  2189 +
  2190 + First, when drawing the hypertext is required, y_pos is initialized at the margin
  2191 + value. Then when a block (t_block ot wt_block) is up to print, the font height value is
  2192 + added to y_pos to obtain the vertical position where a text is printing (see the
  2193 + draw(dtb) tool). Then after each line of text, the above function 'draw_text' add the
  2194 + total_font_height plus the space between to line : y_pos is ready to print a new text.
  2195 +
  2196 + But when there is no more BlockParagraph to print, it's necessary to reduce the final
  2197 + value of y_pos by the font-height value in the below function 'draw_paragraph'.
  2198 +
  2199 +
1050 2200 define Int32
1051 2201 draw_pgraph
1052 2202 (
1053   - WidgetDrawToolBox dtb,
1054   - HyperTextParameters parms,
1055   - List(List(String)) pgraph,
1056   - String -> Int32 x_pos1,
1057   - String -> Int32 x_pos, // for all lines except n#1
1058   - Int32 y_pos,
1059   - (List(String),String) -> String print_text
  2203 + WidgetDrawToolBox dtb,
  2204 + HyperTextParameters parms,
  2205 + List(BlockLine) b_lines,
  2206 + String -> Int32 x_pos_i,
  2207 + String -> Int32 x_pos, // for all lines except n#1
  2208 + Int32 y_pos, // font
  2209 + (BlockContent,Int32) -> BlockContent format_bc
1060 2210 ) =
1061   - if pgraph is
  2211 + if b_lines is
1062 2212 {
1063   - [] then y_pos,
1064   - [h . t] then
1065   - draw_pgraph(dtb,parms,t,x_pos1,x_pos,
1066   - draw_text(dtb,parms,h,x_pos1,x_pos,y_pos,print_text),
1067   - print_text)
  2213 + [] then y_pos-font_height(parms),
  2214 + [h . t] then
  2215 + if h is
  2216 + {
  2217 + first(bc) then //print("xp="+x_pos1(text)+" Fi ["+text+"]\n");
  2218 + with new_bc = format_bc(bc,indent(parms)),
  2219 + draw_text(dtb,parms,new_bc,text_color(bc,link_color(parms)),
  2220 + x_pos_i(concat_bcont(new_bc)),y_pos),
  2221 + middle(bc) then //print("Mi ["+text+"]\n");
  2222 + with new_bc = format_bc(bc,0),
  2223 + draw_text(dtb,parms,new_bc,text_color(bc,link_color(parms)),
  2224 + x_pos(concat_bcont(new_bc)),y_pos)
  2225 + last(bc) then //print("En ["+text+"]\n");
  2226 + with new_bc = bc, //format_bc(h,0),
  2227 + draw_text(dtb,parms,new_bc,text_color(bc,link_color(parms)),
  2228 + x_pos(concat_bcont(new_bc)),y_pos)
  2229 + flast(bc) then //print("Fe ["+text+"]\n");
  2230 + with new_bc = format_bc(bc,indent(parms)),
  2231 + draw_text(dtb,parms,new_bc,text_color(bc,link_color(parms)),
  2232 + x_pos_i(concat_bcont(new_bc)),y_pos),
  2233 + };
  2234 + draw_pgraph(dtb,parms,t,x_pos_i,x_pos,y_pos+total_font_height(parms)+v_space(parms),
  2235 + format_bc)
1068 2236  
1069 2237 }.
1070 2238  
1071 2239  
1072   - *** (6.4) Global function
  2240 + *** (6.5) Global function
1073 2241 *************************
1074 2242  
1075 2243 define One
... ... @@ -1082,7 +2250,7 @@ define One
1082 2250 (String,Int32) -> Int32 x_pos_indent, // (text_lenght,width)
1083 2251 (String,Int32) -> Int32 x_pos, // (text_lenght,width)
1084 2252 Int32 y_pos,
1085   - (List(String),String,Int32) -> String print_text
  2253 + (BlockContent,Int32) -> BlockContent format_bc
1086 2254 ) =
1087 2255 if blocks is
1088 2256 {
... ... @@ -1090,36 +2258,38 @@ define One
1090 2258 [h . t] then
1091 2259 if h is
1092 2260 {
1093   - t_block(pgraph) then
1094   - with t_height = draw_pgraph(dtb,parms,pgraph,
1095   - (String s) |-> x_pos_indent(s,htc_width),
1096   - (String s) |-> x_pos(s,htc_width),
1097   - y_pos+font_height(parms),
1098   - (List(String) ls,String s) |-> print_text(ls,s,htc_width)),
  2261 + t_block(blines) then
  2262 + with t_height =
  2263 + draw_pgraph(dtb,parms,blines,
  2264 + (String s) |-> x_pos_indent(s,htc_width),
  2265 + (String s) |-> x_pos(s,htc_width),
  2266 + y_pos+font_height(parms),
  2267 + (BlockContent bc, Int32 indent) |-> format_bc(bc,htc_width-indent)),
1099 2268 draw_hypertext(dtb,t,parms,htc_width,x_pos_indent,x_pos,
1100   - t_height+v_space(parms),print_text),
1101   - wt_block(pgraph,lr,yp,sp,wid) then
  2269 + t_height,format_bc),
  2270 + wt_block(blines,lr,yp,sp,wid) then
1102 2271 if get_size(wid)(unique) is (wid_width,wid_height) then
1103 2272 redraw(wid)(dtb,clipping_rectangle(dtb));
1104 2273 with t_width = htc_width-wid_width-sp,
1105   - t_height = draw_pgraph(dtb,parms,pgraph,
1106   - (String s) |->
1107   - if lr is
1108   - {
1109   - left then wid_width+sp,
1110   - right then 0
1111   - }+x_pos_indent(s,t_width),
1112   - (String s) |->
1113   - if lr is
1114   - {
1115   - left then wid_width+sp,
1116   - right then 0
1117   - }+x_pos(s,t_width),
1118   - y_pos, //+font_height(parms),
1119   - (List(String) ls,String s) |-> print_text(ls,s,t_width)),
1120   - wid_bottom = y_pos-total_font_height(parms)+wid_height+v_space(parms),
  2274 + t_height =
  2275 + draw_pgraph
  2276 + (dtb,parms,blines,
  2277 + (String s) |-> if lr is
  2278 + {
  2279 + left then wid_width+sp,
  2280 + right then 0
  2281 + }+x_pos_indent(s,t_width),
  2282 + (String s) |-> if lr is
  2283 + {
  2284 + left then wid_width+sp,
  2285 + right then 0
  2286 + }+x_pos(s,t_width),
  2287 + y_pos+min(max(yp,font_height(parms)),
  2288 + wid_height-font_depth(parms)),
  2289 + (BlockContent bc,Int32 indent) |-> format_bc(bc,t_width-indent)),
  2290 + wid_bottom = y_pos+wid_height+v_space(parms),
1121 2291 draw_hypertext(dtb,t,parms,htc_width,x_pos_indent,x_pos,
1122   - max(t_height,wid_bottom),print_text)
  2292 + max(t_height,wid_bottom),format_bc)
1123 2293 }
1124 2294 }.
1125 2295  
... ... @@ -1133,34 +2303,13 @@ define One
1133 2303 ) =
1134 2304 draw_hypertext
1135 2305 (dtb,blocks,parms,htc_width,
1136   - (String s,Int32 width) |->
1137   - if justify(parms) is
1138   - {
1139   - center then margin(parms)+(width-indent(parms)-string_width(parms)(s))/2,
1140   - left then margin(parms)+indent(parms),
1141   - right then margin(parms)+width-indent(parms)-string_width(parms)(s),
1142   - both then margin(parms)+indent(parms)
1143   - },
1144   - (String s,Int32 width) |->
1145   - if justify(parms) is
1146   - {
1147   - center then margin(parms)+(width-string_width(parms)(s))/2,
1148   - left then margin(parms),
1149   - right then margin(parms)+width-string_width(parms)(s),
1150   - both then margin(parms)
1151   - },
1152   - margin(parms),
1153   - (List(String) ls,String s,Int32 width) |->
1154   - if justify(parms) is
1155   - {
1156   - center then s,
1157   - left then s,
1158   - right then s,
1159   - both then
1160   - if ls is [] then s // the last line-text don't need to be justified
1161   - //else if is_ending_paragraph(s) then s
1162   - else justify_text(s,width,string_width(parms))
1163   - }).
  2306 + // x position with indent (for 'first' and 'flast')
  2307 + (String s,Int32 width) |-> compute_margin(parms,s,width,1),
  2308 + // x position without indent (for 'middle' and 'flast')
  2309 + (String s,Int32 width) |-> compute_margin(parms,s,width,0),
  2310 + margin(parms),
  2311 + // formating the block-content to print
  2312 + (BlockContent bc,Int32 width) |-> block_content_format(parms,bc,width)).
1164 2313  
1165 2314  
1166 2315 *** (7) Setting child positions
... ... @@ -1169,11 +2318,11 @@ define One
1169 2318 define One
1170 2319 set_child_positions
1171 2320 (
1172   - WidgetPositionToolBox ptb,
1173   - List(Block) blocks,
1174   - HyperTextParameters parms,
  2321 + WidgetPositionToolBox ptb,
  2322 + List(Block) blocks,
  2323 + HyperTextParameters parms,
1175 2324 Int32 htc_width,
1176   - Int32 y_pos,
  2325 + Int32 y_pos
1177 2326 ) =
1178 2327 if blocks is
1179 2328 {
... ... @@ -1182,14 +2331,14 @@ define One
1182 2331 if h is
1183 2332 {
1184 2333 t_block(pgraph) then
1185   - /*
1186   - set_child_positions(ptb,t,parms,htc_width,
1187   - y_pos+length(text)*(total_font_height(parms)+v_space(parms))),
1188   - */
1189 2334 set_child_positions(ptb,t,parms,htc_width,
1190 2335 y_pos+pgraph_height(pgraph,total_font_height(parms),v_space(parms))),
1191   - wt_block(_,lr,vp,sp,wid) then
  2336 + wt_block(pgraph,lr,vp,sp,wid) then
1192 2337 if get_size(wid)(unique) is (w,h) then
  2338 + with pgraph_height = pgraph_height(pgraph,total_font_height(parms),v_space(parms)),
  2339 + y = y_pos + (if h > pgraph_height
  2340 + then 0
  2341 + else (pgraph_height-h)/2),
1193 2342 set_position(wid)
1194 2343 (ptb,position(
1195 2344 margin(parms)+if lr is
... ... @@ -1197,14 +2346,507 @@ define One
1197 2346 left then 0,
1198 2347 right then htc_width-w
1199 2348 },
1200   - y_pos));
1201   - set_child_positions(ptb,t,parms,htc_width,y_pos+v_space(parms))
  2349 + y));
  2350 + set_child_positions(ptb,t,parms,htc_width,y_pos+max(w,pgraph_height)+v_space(parms))
1202 2351 }
1203 2352 }.
1204 2353  
1205 2354  
  2355 +
  2356 +
  2357 + *** (8) Handler
  2358 + ***************
  2359 +
  2360 +
  2361 + The handler role is to mange the link-widget.
  2362 +
  2363 + When the mouse will come over a link, it's appareance will move to inverted colors,
  2364 + i.e. write with the background-color, and the background move to the usual writing
  2365 + color.
  2366 +
  2367 +
  2368 + The first step to control those effects, is to have in hand a List(LinkRectangle) from
  2369 + the List(Block).
  2370 +
  2371 + A LinkRectangle is formed by
  2372 + . an index;
  2373 + . a List((String,Int32,WidgetRectangle)) where :
  2374 + the String is the text-link,
  2375 + the Int32 is the number pixels for spaces at the beginning of the text
  2376 + the WidgerRectangle begins a the first letter of the text
  2377 + And it's a list because a link may be written on sevral lines.
  2378 +
1206 2379  
1207 2380  
  2381 + *** (8.1) List(LinkRectangle)
  2382 + *****************************
  2383 +
  2384 +type LinkState:
  2385 + normal, // link is waiting mouse or a click
  2386 + mouse_over, // mouse is over the click (transitory state)
  2387 + visited. // link was clicked
  2388 +
  2389 +
  2390 +
  2391 +type LinkRectangle:
  2392 + link_rectangle(Int32 index,
  2393 + List((String,Int32,WidgetRectangle)) lrect,
  2394 + LinkState state,
  2395 + WidgetEventToolBox -> One action).
  2396 +
  2397 +define One
  2398 + print_lkr
  2399 + (
  2400 + List(LinkRectangle) llr
  2401 + ) =
  2402 + if llr is
  2403 + {
  2404 + [] then unique,
  2405 + [h . t] then
  2406 + print(index(h)+" | "
  2407 + +concat(map(((String,Int32,WidgetRectangle) sn_wr) |->
  2408 + if sn_wr is (_,_,wr) then "("+x(wr)+"/"+y(wr)+"/"+u(wr)+"/"+v(wr)+")",
  2409 + lrect(h)))+"\n");
  2410 + print_lkr(t)
  2411 + }.
  2412 +
  2413 +define (String,Int32,WidgetRectangle)
  2414 + compute_rectangle
  2415 + (
  2416 + HyperTextParameters parms,
  2417 + String s,
  2418 + Int32 x_pos,
  2419 + Int32 y_pos
  2420 + ) =
  2421 + with n = string_width(parms)(constant_string(nb_first_spaces(explode(s)),' ')),
  2422 + (s,n,rect(x_pos+n,
  2423 + y_pos-font_height(parms),
  2424 + x_pos+string_width(parms)(s)+1,
  2425 + y_pos+font_depth(parms))).
  2426 +
  2427 +define LinkRectangle
  2428 + new_link_rectangle
  2429 + (
  2430 + String s,
  2431 + Int32 i,
  2432 + WidgetEventToolBox -> One action,
  2433 + HyperTextParameters parms,
  2434 + Int32 x_pos,
  2435 + Int32 y_pos
  2436 + ) =
  2437 + link_rectangle
  2438 + (i,
  2439 + [compute_rectangle(parms,s,x_pos,y_pos)],
  2440 + normal,
  2441 + action).
  2442 +
  2443 +define LinkRectangle
  2444 + add_rectangle
  2445 + (
  2446 + LinkRectangle lr,
  2447 + HyperTextParameters parms,
  2448 + String s,
  2449 + Int32 x_pos,
  2450 + Int32 y_pos
  2451 + ) =
  2452 + link_rectangle
  2453 + (index(lr),
  2454 + [compute_rectangle(parms,s,x_pos,y_pos) . lrect(lr)],
  2455 + normal,
  2456 + action(lr)).
  2457 +
  2458 +
  2459 +define List(LinkRectangle)
  2460 + compute_link_rectangles
  2461 + (
  2462 + String s,
  2463 + Int32 i,
  2464 + WidgetEventToolBox -> One action,
  2465 + HyperTextParameters parms,
  2466 + Int32 x_pos,
  2467 + Int32 y_pos,
  2468 + List(LinkRectangle) llr
  2469 + ) =
  2470 + if llr is
  2471 + {
  2472 + [] then [new_link_rectangle(s,i,action,parms,x_pos,y_pos)],
  2473 + [h . t] then
  2474 + if index(h) = i
  2475 + then [add_rectangle(h,parms,s,x_pos,y_pos) . t]
  2476 + else [h . compute_link_rectangles(s,i,action,parms,x_pos,y_pos,t)]
  2477 + }.
  2478 +
  2479 +
  2480 +define List(LinkRectangle)
  2481 + do_link_rectangles_bc
  2482 + (
  2483 + BlockContent content,
  2484 + HyperTextParameters parms,
  2485 + List(LinkRectangle) so_far,
  2486 + Int32 x_pos,
  2487 + Int32 y_pos
  2488 + ) =
  2489 + if content is
  2490 + {
  2491 + empty then so_far,
  2492 + text(s,bc) then do_link_rectangles_bc(bc,parms,so_far,x_pos+string_width(parms)(s),y_pos),
  2493 + link(s,a,i,bc) then
  2494 + do_link_rectangles_bc
  2495 + (bc,parms,
  2496 + compute_link_rectangles(s,i,a,parms,x_pos,y_pos,so_far),
  2497 + x_pos+string_width(parms)(s),y_pos)
  2498 + }.
  2499 +
  2500 +define (List(LinkRectangle),Int32)
  2501 + do_link_rectangles_lines
  2502 + (
  2503 + List(BlockLine) lines,
  2504 + HyperTextParameters parms,
  2505 + List(LinkRectangle) so_far,
  2506 + (String) -> Int32 x_pos_i,
  2507 + (String) -> Int32 x_pos,
  2508 + Int32 y_pos,
  2509 + (BlockContent,Int32) -> BlockContent format_bc
  2510 + ) =
  2511 + if lines is
  2512 + {
  2513 + [] then (so_far,y_pos),
  2514 + [h . t] then
  2515 + if h is
  2516 + {
  2517 + first(bc) then
  2518 + with f_bc = format_bc(bc,indent(parms)),
  2519 + do_link_rectangles_lines
  2520 + (t,parms,
  2521 + do_link_rectangles_bc
  2522 + (f_bc,parms,so_far,x_pos_i(concat_bcont(f_bc)),y_pos),
  2523 + x_pos_i,x_pos,y_pos+total_font_height(parms)+v_space(parms),format_bc)
  2524 + middle(bc) then
  2525 + with f_bc = format_bc(bc,0),
  2526 + do_link_rectangles_lines
  2527 + (t,parms,
  2528 + do_link_rectangles_bc
  2529 + (f_bc,parms,so_far,x_pos(concat_bcont(f_bc)),y_pos),
  2530 + x_pos_i,x_pos,y_pos+total_font_height(parms)+v_space(parms),format_bc)
  2531 + last(bc) then
  2532 + do_link_rectangles_lines
  2533 + (t,parms,
  2534 + do_link_rectangles_bc
  2535 + (bc,parms,so_far,x_pos(concat_bcont(bc)),y_pos),
  2536 + x_pos_i,x_pos,y_pos+total_font_height(parms)+v_space(parms),format_bc)
  2537 + flast(bc) then
  2538 + with f_bc = format_bc(bc,indent(parms)),
  2539 + do_link_rectangles_lines
  2540 + (t,parms,
  2541 + do_link_rectangles_bc
  2542 + (f_bc,parms,so_far,x_pos_i(concat_bcont(f_bc)),y_pos),
  2543 + x_pos_i,x_pos,y_pos+total_font_height(parms)+v_space(parms),format_bc)
  2544 + }
  2545 + }.
  2546 +
  2547 +
  2548 +define List(LinkRectangle)
  2549 + do_link_rectangles
  2550 + (
  2551 + List(Block) blocks,
  2552 + HyperTextParameters parms,
  2553 + List(LinkRectangle) so_far,
  2554 + Int32 htc_width,
  2555 + (String,Int32) -> Int32 x_pos_indent, // (text_lenght,width)
  2556 + (String,Int32) -> Int32 x_pos, // (text_lenght,width)
  2557 + Int32 y_pos,
  2558 + (BlockContent,Int32) -> BlockContent format_bc
  2559 + ) =
  2560 + if blocks is
  2561 + {
  2562 + [] then so_far,
  2563 + [h . t] then
  2564 + if h is
  2565 + {
  2566 + t_block(lines) then
  2567 + if do_link_rectangles_lines
  2568 + (lines,parms,so_far,
  2569 + (String s) |-> x_pos_indent(s,htc_width),
  2570 + (String s) |-> x_pos(s,htc_width),
  2571 + y_pos+font_height(parms),
  2572 + (BlockContent bc,Int32 indent) |-> format_bc(bc,htc_width-indent))
  2573 + is (llr,new_y_pos) then
  2574 + do_link_rectangles
  2575 + (t,parms,llr,htc_width,x_pos_indent,x_pos,new_y_pos,format_bc),
  2576 +
  2577 + wt_block(lines,lr,vp,sp,wid) then
  2578 + if get_size(wid)(unique) is (wid_width,wid_height) then
  2579 + with t_width = htc_width-wid_width-sp,
  2580 + if do_link_rectangles_lines
  2581 + (lines,parms,so_far,
  2582 + //(String s) |-> x_pos_indent(s,htc_width),
  2583 + (String s) |-> if lr is
  2584 + {
  2585 + left then wid_width+sp,
  2586 + right then 0
  2587 + }+x_pos_indent(s,t_width),
  2588 + //(String s) |-> x_pos(s,htc_width),
  2589 + (String s) |-> if lr is
  2590 + {
  2591 + left then wid_width+sp,
  2592 + right then 0
  2593 + }+x_pos(s,t_width),
  2594 + //y_pos+font_height(parms),
  2595 + y_pos-font_height(parms)+max(vp,font_height(parms)),
  2596 + /*
  2597 + y_pos+min(max(vp,font_height(parms)),
  2598 + wid_height-font_depth(parms))
  2599 + -font_height(parms),
  2600 + */
  2601 + //y_pos+vp,
  2602 + (BlockContent bc,Int32 indent) |-> format_bc(bc,htc_width-indent))
  2603 + is (llr,new_y_pos) then
  2604 +
  2605 + with y = max(y_pos-font_height(parms)+wid_height+v_space(parms),new_y_pos),
  2606 + do_link_rectangles(t,parms,llr,htc_width,x_pos_indent,x_pos,y,format_bc)
  2607 +
  2608 + //do_link_rectangles(t,parms,so_far,htc_width,x_pos_indent,x_pos,y_pos,format_bc)
  2609 + }
  2610 + }.
  2611 +
  2612 +
  2613 +
  2614 +
  2615 +define List(LinkRectangle)
  2616 + do_link_rectangles
  2617 + (
  2618 + List(Block) blocks,
  2619 + HyperTextParameters parms,
  2620 + Int32 htc_width,
  2621 + ) =
  2622 + do_link_rectangles
  2623 + (blocks,parms,(List(LinkRectangle))[],htc_width,
  2624 + (String s,Int32 width) |-> compute_margin(parms,s,width,1),
  2625 + (String s,Int32 width) |-> compute_margin(parms,s,width,0),
  2626 + margin(parms),
  2627 + (BlockContent bc,Int32 width) |-> block_content_format(parms,bc,width)).
  2628 +
  2629 +
  2630 +
  2631 +
  2632 +
  2633 + *** (8.2) HyperText handler
  2634 + ***************************
  2635 +
  2636 + *** (8.2.1) Tools
  2637 + *****************
  2638 +
  2639 +define List(WidgetRectangle)
  2640 + wid_rect
  2641 + (
  2642 + List((String,Int32,WidgetRectangle)) l
  2643 + ) =
  2644 + map(((String,Int32,WidgetRectangle) sn_wr) |-> if sn_wr is (_,_,wr) then wr,l).
  2645 +
  2646 +
  2647 +define Maybe(LinkRectangle)
  2648 + is_mouse_over_lk_rect
  2649 + (
  2650 + List(LinkRectangle) llr,
  2651 + Int32 mx,
  2652 + Int32 my
  2653 + ) =
  2654 + if llr is
  2655 + {
  2656 + [] then failure,
  2657 + [h . t] then
  2658 + if belongs(mx,my,wid_rect(lrect(h)))
  2659 + then success(h)
  2660 + else is_mouse_over_lk_rect(t,mx,my)
  2661 + }.
  2662 +
  2663 +
  2664 +define List(LinkRectangle)
  2665 + move_link_state
  2666 + (
  2667 + List(LinkRectangle) llr,
  2668 + LinkRectangle act_lr, // active link to move to unactiv
  2669 + LinkState state
  2670 + ) =
  2671 + replace_element
  2672 + (llr,
  2673 + (LinkRectangle lr) |-> index(lr)=index(act_lr),
  2674 + link_rectangle(index(act_lr),lrect(act_lr),state,action(act_lr))).
  2675 +
  2676 +
  2677 +define List(WidgetRectangle)
  2678 + get_visited_wid_rect
  2679 + (
  2680 + List(LinkRectangle) llr
  2681 + ) =
  2682 + find_elements(llr,
  2683 + (LinkRectangle lr) |-> state(lr)=visited,
  2684 + (LinkRectangle lr) |-> wid_rect(lrect(lr))).
  2685 +
  2686 +
  2687 + *** (8.2.2) When mouse moves...
  2688 + *******************************
  2689 +
  2690 +define Maybe((List(LinkRectangle),List(WidgetRectangle),LinkRectangle))
  2691 + mouse_over_lk_rect
  2692 + (
  2693 + List(LinkRectangle) llr,
  2694 + Int32 mx,
  2695 + Int32 my,
  2696 + List(LinkRectangle) so_far,
  2697 + ) =
  2698 + if llr is
  2699 + {
  2700 + [] then failure,
  2701 + [h . t] then
  2702 + with wid_rect = wid_rect(lrect(h)),
  2703 + if belongs(mx,my,wid_rect)
  2704 + then with active_lk =
  2705 + link_rectangle(index(h),lrect(h),
  2706 + if state(h) is
  2707 + {
  2708 + normal then mouse_over,
  2709 + mouse_over then mouse_over,
  2710 + visited then visited
  2711 + },action(h)),
  2712 + success(([active_lk . append(t,so_far)],
  2713 + wid_rect,
  2714 + active_lk))
  2715 + else mouse_over_lk_rect(t,mx,my,[h . so_far])
  2716 + }.
  2717 +
  2718 +
  2719 +
  2720 + *** (8.2.3) Generic answer
  2721 + **************************
  2722 +
  2723 +define WidgetAnswer
  2724 + hypertext_handler
  2725 + (
  2726 + WidgetEventToolBox etb,
  2727 + WidgetNormalEvent e,
  2728 + Var(List(LinkRectangle)) lk_rect,
  2729 + Var(Maybe(LinkRectangle)) active_link
  2730 + ) =
  2731 +// print_lkr(*lk_rect);
  2732 + if e is
  2733 + {
  2734 + mouse_gone then
  2735 + if *active_link is
  2736 + {
  2737 + failure then not_handled([]),
  2738 + success(a_lk) then
  2739 + active_link <- failure;
  2740 + handled(wid_rect(lrect(a_lk)))
  2741 + },
  2742 + mouse_move(ks,mx,my) then
  2743 + if mouse_over_lk_rect(*lk_rect,mx,my,[]) is
  2744 + {
  2745 + failure then
  2746 + if *active_link is
  2747 + {
  2748 + failure then not_handled([]),
  2749 + success(a_lk) then
  2750 + active_link <- failure;
  2751 + if state(a_lk) is visited
  2752 + then not_handled([])
  2753 + else lk_rect <- move_link_state(*lk_rect,a_lk,normal);
  2754 + handled(wid_rect(lrect(a_lk)))
  2755 + },
  2756 + success(s) then if s is (new_lk_rect,wid_rect,a_lk)
  2757 + then lk_rect <- new_lk_rect;
  2758 + active_link <- success(a_lk);
  2759 + handled(wid_rect)
  2760 + },
  2761 + mouse_click(ks,mc,mx,my) then
  2762 + if *active_link is
  2763 + {
  2764 + failure then not_handled([]),
  2765 + success(a_lk) then
  2766 + if mc is
  2767 + {
  2768 + left_down then not_handled([]),
  2769 + left_up then
  2770 + lk_rect <- move_link_state(*lk_rect,a_lk,visited);
  2771 + action(a_lk)(etb);
  2772 + active_link <- failure;
  2773 + handled(wid_rect(lrect(a_lk))),
  2774 + middle_down then not_handled([]),
  2775 + middle_up then not_handled([]),
  2776 + right_down then not_handled([]),
  2777 + right_up then not_handled([]),
  2778 + }
  2779 + }
  2780 + }.
  2781 +
  2782 +
  2783 + *** (8.3) Draw List(LinkRectangle)
  2784 + **********************************
  2785 +
  2786 +define List((String,Int32,WidgetRectangle))
  2787 + rect_to_draw
  2788 + (
  2789 + List(LinkRectangle) llr,
  2790 + LinkState ls
  2791 + ) =
  2792 + if llr is
  2793 + {
  2794 + [] then [],
  2795 + [h . t] then if ls=state(h) then append(lrect(h),rect_to_draw(t,ls)) else rect_to_draw(t,ls)
  2796 + }.
  2797 +
  2798 +
  2799 +define One
  2800 + draw_links_mouse_over
  2801 + (
  2802 + WidgetDrawToolBox dtb,
  2803 + HyperTextParameters parms,
  2804 + List((String,Int32,WidgetRectangle)) rect_to_draw,
  2805 + RGB text_color
  2806 + ) =
  2807 + if rect_to_draw is
  2808 + {
  2809 + [] then unique,
  2810 + [h . t] then
  2811 + if h is (text,n,wid_rect) then
  2812 + draw(dtb)(wid_rect,lighten(text_color));
  2813 + forget(draw_text(dtb,parms,text,(RGB _) |-> darken(text_color), //link_color(parms), //rgb(0,0,0),
  2814 + x(wid_rect)-n,y(wid_rect)+font_height(parms)));
  2815 + draw_links_mouse_over(dtb,parms,t,text_color)
  2816 + }.
  2817 +
  2818 +define One
  2819 + draw_links_visited
  2820 + (
  2821 + WidgetDrawToolBox dtb,
  2822 + HyperTextParameters parms,
  2823 + List((String,Int32,WidgetRectangle)) rect_to_draw
  2824 + ) =
  2825 + if rect_to_draw is
  2826 + {
  2827 + [] then unique,
  2828 + [h . t] then
  2829 + if h is (text,n,wid_rect) then
  2830 + with y = y(wid_rect)+font_height(parms),
  2831 + v_color = darken(link_color(parms)),
  2832 + forget(draw_text(dtb,parms,text,(RGB _) |-> v_color, x(wid_rect)-n,y));
  2833 + draw(dtb)(rect(x(wid_rect),y+1,x(wid_rect)+string_width(parms)(text),y+2),v_color);
  2834 + draw_links_visited(dtb,parms,t)
  2835 + }.
  2836 +
  2837 +define One
  2838 + draw_links
  2839 + (
  2840 + WidgetDrawToolBox dtb,
  2841 + Var(List(LinkRectangle)) lk_rect,
  2842 + Var(Maybe(LinkRectangle)) active_lk,
  2843 + HyperTextParameters parms,
  2844 + Int32 htc_width
  2845 + ) =
  2846 + draw_links_mouse_over
  2847 + (dtb,parms,rect_to_draw(*lk_rect,mouse_over),text_color(effect(parms)));
  2848 + draw_links_visited(dtb,parms,rect_to_draw(*lk_rect,visited)).
  2849 +
1208 2850  
1209 2851 *** () Creating the widget
1210 2852 **************************
... ... @@ -1220,22 +2862,32 @@ public define Widget
1220 2862 Int32 v_space, // number of pixels between lines
1221 2863 Int32 indent, // number of pixels before beginning of paragraphs
1222 2864 WidgetTextJustify justify, // how to justify the text
1223   - HyperTextContent content
  2865 + HyperTextContent content,
  2866 + Maybe(RGB) lk_color // link_color
1224 2867 ) =
1225 2868  
1226 2869 with sfi = get_font_info(font),
1227 2870 font_height = int8_to_int32(height(sfi)),
1228   - total_font_height = font_height+int8_to_int32(depth(sfi)),
  2871 + font_depth = int8_to_int32(depth(sfi)),
  2872 + total_font_height = font_height+font_depth,
1229 2873 string_width = (String s) |-> printed_text_width(font,s),
1230   - parms = ht_parms(font,font_height,total_font_height,margin,v_space,indent,
1231   - effect,justify,string_width),
  2874 + parms = ht_parms(font,font_height,font_depth,total_font_height,margin,v_space,indent,
  2875 + effect,justify,string_width,
  2876 + if lk_color is
  2877 + {
  2878 + failure then darken(text_color(effect)),
  2879 + success(rgb) then rgb
  2880 + }),
1232 2881  
1233 2882 htc_width = compute_width(width,content,string_width), // without margins, for the content
1234 2883 is_too_large = (String s,Int32 n) |-> (string_width(s) > n),
1235 2884 blocks = to_blocks(content,htc_width,margin,indent,total_font_height+v_space,is_too_large),
1236 2885 ht_width = htc_width+(2*margin),
1237 2886 ht_height = height(blocks,total_font_height,v_space)+(2*margin),
  2887 + lk_rect = var( (List(LinkRectangle)) do_link_rectangles(blocks,parms,htc_width)),
  2888 + active_link = var( (Maybe(LinkRectangle)) failure),
1238 2889  
  2890 +
1239 2891 create_widget(
1240 2892 /* set child_positions */
1241 2893 (WidgetPositionToolBox ptb) |->
... ... @@ -1250,17 +2902,20 @@ public define Widget
1250 2902 {
1251 2903 failure then unique,
1252 2904 success(bg) then draw(dtb)(rect(0,0,ht_width,ht_height),bg)
1253   - }; draw_hypertext(dtb,blocks,parms,htc_width),
  2905 + };
  2906 + draw_hypertext(dtb,blocks,parms,htc_width);
  2907 + draw_links(dtb,lk_rect,active_link,parms,htc_width),
1254 2908  
1255 2909 /* duplicate */
1256 2910 (One u) |-> create_hypertext
1257   - (font,effect,background,width,margin,v_space,indent,justify,content),
  2911 + (font,effect,background,width,margin,v_space,indent,justify,content,lk_color),
1258 2912  
1259 2913 /* Change size */
1260 2914 (Int32 w, Int32 h) |-> unique,
1261 2915  
1262 2916 /* event handling */
1263   - (WidgetEventToolBox etb, WidgetNormalEvent e) |-> not_handled([]),
  2917 + (WidgetEventToolBox etb, WidgetNormalEvent e) |->
  2918 + hypertext_handler(etb,e,lk_rect,active_link),
1264 2919  
1265 2920 /* monitoring */
1266 2921 (List(WidgetRegistration)) []
... ...
anubis_dev/library/widgets3/resizer.anubis
... ... @@ -11,8 +11,8 @@
11 11 Authors: Alain Proutรฉ
12 12  
13 13  
14   -read widgets3/widget.anubis
15   -read widgets3/tools.anubis
  14 +read widget.anubis
  15 +read tools.anubis
16 16  
17 17  
18 18 This file defines the 'resizer' widget. This widget appears as a small square with 4
... ...
anubis_dev/library/widgets3/scrollbar.anubis
... ... @@ -13,8 +13,8 @@
13 13  
14 14  
15 15  
16   -read widgets3/widget.anubis
17   -read widgets3/tools.anubis
  16 +read widget.anubis
  17 +read tools.anubis
18 18  
19 19  
20 20 A scrollbar is a thin rectangle (either vertical of horizontal) with a button (the
... ...
anubis_dev/library/widgets3/simple_example.anubis
... ... @@ -41,13 +41,13 @@
41 41  
42 42  
43 43 read tools/basis.anubis
44   -read widgets3/host_window.anubis
45   -read widgets3/widget.anubis
46   -read widgets3/tools.anubis
47   -read widgets3/table.anubis
48   -read widgets3/check_box.anubis
49   -read widgets3/button.anubis
50   -read widgets3/text.anubis
  44 +read host_window.anubis
  45 +read widget.anubis
  46 +read tools.anubis
  47 +read table.anubis
  48 +read check_box.anubis
  49 +read button.anubis
  50 +read text.anubis
51 51  
52 52  
53 53 global define One
... ...
anubis_dev/library/widgets3/simple_window.anubis
... ... @@ -13,7 +13,7 @@
13 13  
14 14  
15 15  
16   -read widgets3/widget.anubis
  16 +read widget.anubis
17 17  
18 18  
19 19 This file defines simple 'nude' windows. If you need more sophisticated windows (with
... ...
anubis_dev/library/widgets3/space.anubis
... ... @@ -11,7 +11,7 @@
11 11 Olivier Duvernois
12 12  
13 13  
14   -read widgets3/widget.anubis
  14 +read widget.anubis
15 15  
16 16  
17 17  
... ...
anubis_dev/library/widgets3/table.anubis
... ... @@ -13,8 +13,8 @@
13 13  
14 14  
15 15  
16   -read widgets3/widget.anubis
17   -read widgets3/tools.anubis
  16 +read widget.anubis
  17 +read tools.anubis
18 18  
19 19  
20 20 In this file the 'table' widget is defined. A table enables to display a set of
... ... @@ -870,7 +870,7 @@ define WidgetAnswer
870 870 When a mouse event arrives, we call 'update_impact' and 'transmit_event'
871 871 successively. The two answers must be merged into a single answer.
872 872  
873   -read widgets3/tools.anubis
  873 +read tools.anubis
874 874  
875 875 define WidgetAnswer
876 876 merge_answers
... ...
anubis_dev/library/widgets3/table_example.anubis
1 1  
2 2  
3 3  
4   -read widgets3/host_window.anubis
5   -read widgets3/table.anubis
6   -read widgets3/space.anubis
7   -read widgets3/check_box.anubis
8   -read widgets3/button.anubis
9   -read widgets3/image.anubis
10   -read widgets3/scrollbar.anubis
11   -read widgets3/simple_window.anubis
12   -read widgets3/window.anubis
13   -read widgets3/text.anubis
  4 + read widgets3/host_window.anubis
  5 + read widgets3/table.anubis
  6 + read widgets3/space.anubis
  7 + read widgets3/check_box.anubis
  8 + read widgets3/button.anubis
  9 + read widgets3/image.anubis
  10 + read widgets3/scrollbar.anubis
  11 + read widgets3/simple_window.anubis
  12 + read widgets3/window.anubis
  13 + read widgets3/text.anubis
  14 +
14 15  
  16 +read host_window.anubis
  17 +read table.anubis
  18 +read space.anubis
  19 +read check_box.anubis
  20 +read button.anubis
  21 +read image.anubis
  22 +read scrollbar.anubis
  23 +read simple_window.anubis
  24 +read window.anubis
  25 +read text.anubis
  26 +
15 27 define List(WidgetCell)
16 28 cells_color
17 29 (
... ...
anubis_dev/library/widgets3/text.anubis
... ... @@ -17,8 +17,8 @@
17 17  
18 18  
19 19  
20   -read widgets3/widget.anubis
21   -read widgets3/tools.anubis
  20 +read widget.anubis
  21 +read tools.anubis
22 22  
23 23  
24 24 public define Widget
... ...
anubis_dev/library/widgets3/tickets_holder.anubis
... ... @@ -11,8 +11,8 @@
11 11 Authors: Alain Proutรฉ
12 12  
13 13  
14   -read widgets3/widget.anubis
15   -read widgets3/tools.anubis
  14 +read widget.anubis
  15 +read tools.anubis
16 16  
17 17  
18 18 This file defines the 'ticket holder' widget. This widget has a content but is
... ...
anubis_dev/library/widgets3/tools.anubis
... ... @@ -47,7 +47,8 @@
47 47  
48 48  
49 49  
50   -read widgets3/widget.anubis
  50 + read widgets3/widget.anubis
  51 +read widget.anubis
51 52  
52 53  
53 54 *** (1) Style parameters.
... ...
anubis_dev/library/widgets3/try_ht.anubis
1 1  
2 2  
3 3  
4   -read widgets3/host_window.anubis
5   -read widgets3/widget.anubis
6   -read widgets3/tools.anubis
  4 +read host_window.anubis
  5 +read widget.anubis
  6 +read tools.anubis
7 7  
8 8 read hypertext.anubis
9 9 read system_colors/rgb.anubis
... ... @@ -17,7 +17,7 @@ define String
17 17  
18 18 define String
19 19 hypertext1 =
20   - "Aliรฉnor d'Aquitaine est probablement la plus connue des reines du Moyen-Age. Sa biographie exceptionnelle explique sans doute cette popularitรฉ : double mariage avec les rois de France et d'Angleterre, destinรฉe de ses onze enfants parmi lesquels figurent Richard Coeur de Lion et Jean sans Terre, rรฉvolte contre son mari et longue captivitรฉ, mort octogรฉnaire...".".
  20 + "Aliรฉnor d'Aquitaine est probablement la plus connue des reines du Moyen-Age. Sa biographie exceptionnelle explique sans doute cette popularitรฉ : double mariage avec les rois de France et d'Angleterre, destinรฉe de ses onze enfants parmi lesquels figurent Richard Coeur de Lion et Jean sans Terre, rรฉvolte contre son mari et longue captivitรฉ, mort octogรฉnaire...".
21 21  
22 22 define String
23 23 hypertext2 =
... ... @@ -25,8 +25,8 @@ define String
25 25  
26 26 define String
27 27 hypertext21 =
28   - "A ces รฉvรฉnements s'ajoute la lรฉgende noire, forgรฉe de toute piรจce y compris de son vivant, autour de sa personne.".
29   -
  28 + "A ces รฉvรฉnements s'ajoute la lรฉgende noire, forgรฉe de toute piรจce y compris de son vivant, autour de sa personne.".
  29 +
30 30 define String
31 31 hypertext22 =
32 32 "Il faut dรฉgager la vie d'Aliรฉnor de ces differents ajouts afin de percevoir en elle un type social de la reine, duchesse ou comtesse, somme tout assez courant au XII siรจcle.".
... ... @@ -86,13 +86,14 @@ define LinkWidget
86 86 define String
87 87 hypertext_l2 =
88 88 "\ et Jean sans Terre, rรฉvolte contre son mari \& longue captivitรฉ, mort octogรฉnaire... A ces รฉvรฉnements s'ajoute la lรฉgende noire, forgรฉe de toute piรจce y compris de son vivant, autour de sa personne. Il faut dรฉgager la vie d'Aliรฉnor de ces differents ajouts afin de percevoir en elle un type social de la reine, duchesse ou comtesse, somme tout assez courant au XII siรจcle.".
  89 +
89 90 define String
90 91 hypertext_l21 =
91 92 "\ et Jean sans Terre, rรฉvolte contre son mari \& longue captivitรฉ, mort octogรฉnaire...".
92 93  
93 94 define String
94 95 hypertext_l22 =
95   - "A ces รฉvรฉnements s'ajoute la lรฉgende noire, forgรฉe de toute piรจce y compris de son vivant, autour de sa personne. Il faut dรฉgager la vie d'Aliรฉnor de ces differents ajouts afin de percevoir en elle un type social de la reine, duchesse ou comtesse, somme tout assez courant au XII siรจcle.".
  96 + " A ces รฉvรฉnements s'ajoute la lรฉgende noire, forgรฉe de toute piรจce y compris de son vivant, autour de sa personne. Il faut dรฉgager la vie d'Aliรฉnor de ces differents ajouts afin de percevoir en elle un type social de la reine, duchesse ou comtesse, somme tout assez courant au XII siรจcle.".
96 97  
97 98 define String
98 99 hypertext_l23 =
... ... @@ -238,7 +239,7 @@ define One
238 239 {
239 240 failure then print("cannot load font \n"),
240 241 success(font) then
241   -
  242 +
242 243 forget(open_host_window(10,10,"HT & FloatWid / Center",
243 244 create_hypertext
244 245 (font,normal(red),failure,350,3,2,3,center,
... ... @@ -262,7 +263,7 @@ define One
262 263 forget(open_host_window(10,10,"HT & FloatWid / left",
263 264 create_hypertext
264 265 (font,normal(red),failure,350,3,2,3,left,
265   - //hypertext1+left_fw(10,create_image("alienor.jpg"))+hypertext2)));
  266 + //hypertext1+left_fw(10,create_image("alienor.jpg"))+hypertext2
266 267 hypertext1+left_fw(10,create_image("alienor.jpg"))+hypertext21+"\n"+hypertext22+empty
267 268 ,failure)));
268 269  
... ... @@ -377,6 +378,38 @@ define One
377 378 }.
378 379  
379 380  
  381 +define One
  382 + float_wid_link_lr =
  383 + if load_system_font(default_font) is
  384 + {
  385 + failure then print("cannot load font \n"),
  386 + success(font) then
  387 +/*
  388 + forget(open_host_window(10,10,"HT & FloatWid / left",
  389 + create_hypertext
  390 + (font,normal(red),failure,350,3,2,3,left,
  391 + hypertext_l1+link_richard+hypertext_l21
  392 + +left_fw(10,create_image("alienor.jpg"))+hypertext_l22+empty,
  393 + success(yellow))));
  394 +*/
  395 + forget(open_host_window(400,10,"HT & FloatWid / left",
  396 + create_hypertext
  397 + (font,normal(red),failure,350,3,2,3,both,
  398 + hypertext_l1
  399 + +left_fw(10,create_image("alienor.jpg"))
  400 + +link_richard+hypertext_l21+hypertext_l22+empty,
  401 + success(yellow))));
  402 +
  403 + forget(open_host_window(10,10,"HT & FloatWid / Justify",
  404 + create_hypertext
  405 + (font,normal(red),failure,350,3,2,3,both,
  406 + hypertext_l1+link_richard+hypertext_l21
  407 + +left_fw(10,create_image("alienor.jpg"))+hypertext_l22+empty,
  408 + success(yellow))))
  409 +
  410 + }.
  411 +
  412 +
380 413 *** Summary
381 414 ***********
382 415  
... ... @@ -388,15 +421,16 @@ type WidgetHT:
388 421  
389 422 define List(WidgetHT)
390 423 all_ht =
391   - [widget_ht(1, "Text format", (One u) |-> text_format),
392   - widget_ht(2, "Text effect", (One u) |-> text_effect),
393   - widget_ht(3, "Text & pos-widget LR", (One u) |-> text_pos_wid_lr),
394   - widget_ht(4, "Text & pos-widget CJ", (One u) |-> text_pos_wid_cj),
395   - widget_ht(5, "Text & float-widget CJ", (One u) |-> text_float_wid_cj),
396   - widget_ht(6, "Text & float-widget LR", (One u) |-> text_float_wid_lr),
397   - widget_ht(7, "Text & Link", (One u) |-> text_link),
398   - widget_ht(8, "Pos Wid & Link LR", (One u) |-> pos_wid_link_lr),
399   - widget_ht(9, "Pos Wid & Link CJ", (One u) |-> pos_wid_link_cj)].
  424 + [widget_ht(1, "Text format", (One u) |-> text_format),
  425 + widget_ht(2, "Text effect", (One u) |-> text_effect),
  426 + widget_ht(3, "Text & pos-widget LR", (One u) |-> text_pos_wid_lr),
  427 + widget_ht(4, "Text & pos-widget CJ", (One u) |-> text_pos_wid_cj),
  428 + widget_ht(5, "Text & float-widget CJ", (One u) |-> text_float_wid_cj),
  429 + widget_ht(6, "Text & float-widget LR", (One u) |-> text_float_wid_lr),
  430 + widget_ht(7, "Text & Link", (One u) |-> text_link),
  431 + widget_ht(8, "Pos Wid & Link LR", (One u) |-> pos_wid_link_lr),
  432 + widget_ht(9, "Pos Wid & Link CJ", (One u) |-> pos_wid_link_cj),
  433 + widget_ht(10, "Float Wid & Link LR", (One u) |-> float_wid_link_lr)].
400 434  
401 435  
402 436 define One
... ...
anubis_dev/library/widgets3/window.anubis
... ... @@ -12,13 +12,13 @@
12 12 Olivier Duvernois
13 13  
14 14  
15   -read widgets3/widget.anubis
16   -read widgets3/table.anubis
17   -read widgets3/simple_window.anubis
18   -read widgets3/scrollbar.anubis
19   -read widgets3/box.anubis
20   -read widgets3/resizer.anubis
21   -read widgets3/tickets_holder.anubis
  15 +read widget.anubis
  16 +read table.anubis
  17 +read simple_window.anubis
  18 +read scrollbar.anubis
  19 +read box.anubis
  20 +read resizer.anubis
  21 +read tickets_holder.anubis
22 22  
23 23 This 'window' widget is a combination of several 'atomic' widgets. Actually, the window
24 24 widget is a table designed as follows:
... ...