source: project/wiki/eggref/4/bb @ 20568

Last change on this file since 20568 was 20568, checked in by felix winkelmann, 11 years ago

new egg versions

File size: 42.7 KB
Line 
1[[tags: egg]]
2
3== bb
4
5[[toc:]]
6
7=== Description
8
9A very simple GUI toolkit based on [[http://www.fltk.org/|FLTK]].
10This extension library has been tested with FLTK versions 1.1.4 and 1.1.6.
11
12=== Author
13
14[[/users/felix winkelmann|felix winkelmann]]
15
16=== Requirements
17
18* [[silex]]
19* [[easyffi]]
20* [[matchable]]
21
22=== Download
23
24[[http://www.call-with-current-continuation.org/eggs/bb.egg|bb.egg]]
25
26=== Documentation
27
28==== Base interface
29
30===== bb:init
31
32<procedure>(bb:init [SCHEME])</procedure>
33
34Initializes the toolkit. The optional argument {{SCHEME}} may be a string naming
35a particular graphical scheme (possible values {{"none"}} or {{"plastic"}})
36or {{#f}} (meaning the default). Calling this procedure a subsequent time has no effect.
37
38===== bb:widget?
39
40<procedure>(bb:widget? X)</procedure>
41
42Returns {{#t}} if {{X}} is a widget, or {{#f}} otherwise.
43
44===== bb:make-widget
45
46<procedure>(bb:make-widget TYPE [W H])</procedure>
47<procedure>(bb:make-widget TYPE X Y W H)</procedure>
48
49Creates and returns a widget of the type given by the symbol {{TYPE}}.
50Possible widget types are:
51
52; window :  a normal top-level window
53
54; double-window : a double-buffered window
55
56; button :
57
58; return-button :
59
60; choice-button :
61
62; menu-button :
63
64; check-box :
65
66; entry :  a single-line text field
67
68; edit :  a multiline text field
69
70; text-editor : a full text editor with scroll bars
71
72; int-entry : text field for editing integer numbers. Value is a string rather than number.
73
74; float-entry : text field for editing float numbers. Value is a string rather than number.
75
76; counter :  a "spin-box" like widget
77
78; dial :  a "clock"-type dial widget
79
80; clock : a proper clock
81
82; label :
83
84; slider :
85
86; adjuster :  a widget for changing a value by dragging
87
88; roller :  another adjuster-like widget
89
90; list :  a vertical list of strings
91
92; radio-button :
93
94; progress :
95
96; tabs :  a collection of tab widgets
97
98; tile :  groups widgets with draggable boundaries
99
100; pack :  packs widgets vertically or horizontally
101
102; group :  a generic grouping widget
103
104; scroll :  a group widget with scrollable contents
105
106; light-button :  like a checkbox with a "light"
107
108; menu-bar :
109
110; glwindow : a window that contains OpenGL graphics
111
112; live-image : an image that will be redrawn from a given pointer
113
114; tree : a tree control. Available only if bb was compiled with [[http://www.osc.edu/~jbryan/FLU|FLU]] support.
115
116; table : a simple table widget
117
118; html-view : a simple html viewer
119
120
121A top-level window created with {{bb:make-widget}} will not automatically be shown until
122{{bb:show}} has been called.
123
124===== bb:property
125
126<procedure>(bb:property WIDGET PROPERTY)</procedure>
127<setter>(set! (bb:property WIDGET PROPERTY) VALUE)</setter>
128
129Gets or sets the properties given in {{PROPERTY1 ...}} (which should be symbols).
130Values may also be lists, in that case the values are combined (this only applies to certain properties - see below).
131
132>Some properties may be set for individual items of the {{tree}} and {{table}} widgets.
133They are specified in the form {{(list WIDGET ITEMID)}}.
134{{ITEMID}} is either unique item id or one of the symbols:
135
136* {{root}}
137* {{connector}}
138* {{leaf}}
139* {{branch}}
140
141In this case the {{VALUE}} will be applied either to root node, connector or
142all subsequent branches or leaves added to the tree.
143
144{{width}} and {{align}} properties can be applied to the {{table}} widget's columns.
145
146Allowed widget properties are:
147
148; x :
149
150; y :
151
152; width :
153
154; height : Position and dimensions (integer). Positions are always relative to the container. {{Width}} property may be set for {{connector}} item of the {{tree}} widget.
155
156; text : The text of a label, button, text-fields or {{html-view}}. Also the title of a window. For the {{tree}} widget the value is the label of the subitem. For the {{table}} widget one can specify individual cells in the form {{(list TABLEWIDGET ROW COLUMN)}}. The negative {{ROW}} means column header.
157
158; value : The value of a "range" widget ({{slider}}, {{roller}}, {{adjuster}}, {{counter}} or {{dial}}), in which case it should be a number. For {{check-box}} and {{radio-button}} widgets the value should be a boolean. For {{list}} widgets, the value is the index of the highlighted item, starting from 1. The value of the {{choice-button}} widget is the index of the selected item. For {{tree}} widgets, the value is the unique id of the currently selected item. The value of the {{html-view}} is a current file name.
159
160; box : The ''box type''. A box type is one of the symbols
161* no-box
162* flat-box
163* up-box
164* down-box
165* up-frame
166* down-frame
167* thin-up-box
168* thin-down-box
169* thin-up-frame
170* thin-down-frame
171* engraved-box
172* embossed-box
173* engraved-frame
174* embossed-frame
175* border-box
176
177; callback : The callback procedure that is invoked when the value of a widget changes. See the {{when}} property for more information. For {{tree}} widgets one can obtain additional information from properties {{callback-reason}} and {{callback-node}}.
178
179; image : An image that should be drawn into the widget. See {{bb:image}} for how to load images. You can also set the value {{image}} property to a string, which will load any image file with this name automatically. The value may also be a pointer object pointing to a data buffer for a {{live-image}} widget. Images may be set for a {{tree}} widget items. If subitem is the {{branch}} or {{connector}}, then {{VALUE}} can specify pair of the images: for closed and open state respectively.
180
181; type : The ''type'' of a widget. The possible type symbols depend on what kind of widget it applies to:
182
183scroll:
184
185* scroll-horizontal
186* scroll-vertical
187* scroll-both
188* scroll-always-on
189* scroll-horizontal-always
190* scroll-vertical-always
191* scroll-both-always
192
193(may be combined)
194
195slider:
196
197* vertical-fill-slider
198* horizontal-fill-slider
199* vertical-nice-slider
200* horizontal-nice-slider
201
202dial:
203
204* normal-dial
205* line-dial
206* fill-dial
207* resizable
208
209; modal : Whether a window is resizable and/or modal.
210
211; direction : The direction of a widget, which should be one of the symbols {{horizontal}} or {{vertical}}.
212
213; color : The background color of a widget. This can either be a value returned by {{bb:rgb}} or one of the following symbols:
214
215* gray0
216* dark3
217* dark2
218* dark1
219* light1
220* light2
221* light3
222* gray
223* black
224* red
225* green
226* yellow
227* blue
228* magenta
229* cyan
230* dark-red
231* dark-green
232* dark-yellow
233* dark-blue
234* dark-magenta
235* dark-cyan
236* white
237
238The color attribute of a {{live-image}} widget designates the number of color channels (1-4).
239Also is applicable to the {{connector}} subitem of the {{tree}} widget.
240
241; image-width : The width of a {{live-image}} widget.
242
243; image-height : The height of a {{live-image}} widget.
244
245; focus : Whether this widget has the input focus. Calling {{bb:property}} for this property will always return 0 (but setting it will change the focus to the target widget).
246
247; spacing : The spacing inside group widgets (in pixels).
248
249; maximum : Maximum value for range widgets.
250
251; minimum : Minimum value for range widgets.
252
253; x-position : X-position for {{scroll}} widgets.
254
255; y-position : Y-position for {{scroll}} widgets.
256
257; text-color : Text color. Can also be applied to the {{tree}} subitems.
258
259; text-size : Text size. Can also be applied to the {{tree}} subitems.
260
261; text-font : Text font, which may be one of the following:
262
263* helvetica
264* helvetica-bold
265* helvetica-italic
266* helvetica-bold-italic
267* courier
268* courier-bold
269* courier-italic
270* courier-bold-italic
271* times
272* times-bold
273* times-italic
274* times-bold-italic
275* symbol
276* screen
277* screen-bold
278
279Can be specified for the {{tree}} branches and leaves.
280
281; label-color : Color of a label.
282
283; label-size : Size of a label.
284
285; label-font : Font of a label.
286
287; selection-color : The color of the selection in a text widget or the color of indicators in other widgets.
288
289; position : The position of the caret in an {{entry}}, {{edit}} or {{text-editor}} widget. Setting the position to {{-1}} will move the caret to the end of the current text.
290
291; mark : The position of the selection mark in an {{entry}}, {{edit}} or {{text-editor}} widget. The text between the selection mark and the caret is the current selection.
292
293; selection : The currently selected text in an {{entry}}, {{edit}} or {{text-editor}} widget. When set, the value should be a pair containing start and end position of the selection in the buffer.
294
295; tooltip : A string that should be displayed, when the mouse hovers over a widget.
296
297; visible : Whether a widget is visible or not.
298
299; resizable-widget : The widget in a group, which should be exclusively resizable.
300
301; valid-context : A flag indicating whether the GL context for a {{glwindow}} is already initialized.
302
303; read-only : If true, an {{edit}} or {{entry}} widget can not be changed by the user.
304
305; align : The alignment of the widget label. May be combination of the following symbols:
306
307* center
308* top
309* bottom
310* left
311* right
312* inside
313* text-over-image
314* image-over-text
315* clip
316* wrap
317
318; when : An indicator when a widgets callback should be invoked. The default behaviour depends on the type of the widget. Possible settings are:
319
320* never - never invoked the callback
321* changed - when the widget's value changes
322* released - when the button or key is released and the value changes
323* enter - when the enter key is pressed and the value changes
324* always - modifier for {{released}} or {{enter}}, that indicates the callback should be invoked, even if the value doesn't change
325
326The default behaviour is to invoke the callback whenever the value of
327a widget changes, when a {{window}} is closed, when {{glwindow}} needs
328to be redrawn, or a {{button}} or {{list}} item has been clicked.
329
330; handler : The callback procedure that is invoked when the event occurs. The event is passed in a
331first (and only) argument to the handler. A event is one of the symbols:
332
333* no-event
334* push
335* release
336* enter
337* leave
338* drag
339* focus
340* unfocus
341* keydown
342* keyup
343* close
344* move
345* shortcut
346* deactivate
347* activate
348* hide
349* show
350* paste
351* selectionclear
352* mousewheel
353* dnd-enter
354* dnd-drag
355* dnd-leave
356* dnd-release
357* unknown
358
359Additional information about event can be obtained with {{bb:event}} procedure.
360Returning {{#f}} from handler indicates that widget is not interested in handling
361this event. {{#t}} means that event was successfully handled. Any other value leads to
362invoking default handler of this widget.
363
364The {{html-view}} widget's {{handler}} is invoked when user tries to follow
365the link (which URI is passed as an argument). {{Handler}} should return either the name
366of the temporary file or {{#f}} and set the {{text}} property.
367
368; callback-reason : The reason for callback. Available only for {{tree}} widget. Valid values are:
369
370* hilighted
371* unhilighted
372* selected
373* unselected
374* opened
375* closed
376* double-click
377* widget-callback
378* moved-node
379* new-node
380* nothing
381
382; callback-node: The unique id of the node that caused callback. Available only for {{tree}} widget.
383
384===== bb:event
385
386<procedure>(bb:event PROPERTY)</procedure>
387<setter>(set! (bb:event PROPERTY) VALUE)</setter>
388
389Gets or sets the event properties given in {{PROPERTY}} (which should be symbol).
390Only {{click?}} and {{clicks}} properties can be set.
391
392Allowed event properties are:
393
394* alt
395* ctrl
396* shift
397* click?
398* button1
399* button2
400* button3
401
402Whether mouse or special keyboard button was pressed.
403
404* clicks
405
406The number of clicks ({{N - 1}} for {{N}} clicks)
407
408* x
409* y
410* x-root
411* y-root
412* dx
413* dy
414
415Coordinates.
416
417* length
418* text
419
420The length and text.
421
422* key
423
424Which key was pressed. Possible values are:
425
426* character
427
428for ordinary keys
429
430* the pair of {{character}} and {{kp}}
431
432for keypad keys
433
434* backspace
435* tab
436* enter
437* pause
438* scroll-lock
439* escape
440* home
441* left
442* up
443* right
444* down
445* page-up
446* page-down
447* end
448* print
449* insert
450* menu
451* help
452* num-lock
453* shift-l
454* shift-r
455* control-l
456* control-r
457* caps-lock
458* meta-l
459* meta-r
460* alt-l
461* alt-r
462* delete
463* F1...F24
464* button1
465* button2
466* button3
467* unknown
468
469for special keys.
470
471===== bb:message
472
473<procedure>(bb:message MESSAGE)</procedure>
474<procedure>(bb:message TYPE MESSAGE [BUTTON1 [BUTTON2 [BUTTON3]]])</procedure>
475
476Shows a message box of type {{TYPE}} with the string {{MESSAGE}}.
477The optional {{BUTTON}} arguments should be strings the specify the text of any
478extra buttons. Message types may be:
479
480; message : information dialog with an "OK" button.
481
482; alert : alert box with an "OK" button.
483
484; ask : a "yes/no" request dialog.
485
486; choice : a request button with three choices.
487
488===== bb:run
489
490<procedure>(bb:run [WAIT])</procedure>
491
492Processes events. If {{WAIT}} is true or not specified, {{bb:run}} does
493not return until the last window closes. If {{WAIT}} is a number, then {{bb:run}}
494returns after that many seconds, or earlier, if no events are queued.
495
496===== bb:add!
497
498<procedure>(bb:add! WIDGET ITEM [CALLBACK [SHORTCUT]])</procedure>
499<procedure>(bb:add! LISTWIDGET TEXT [POSITION])</procedure>
500<procedure>(bb:add! TREEWIDGET TEXT [PARENT [POSITION [SUBWIDGET]]])</procedure>
501<procedure>(bb:add! TABLEWIDGET [CELLTEXT ...])</procedure>
502<procedure>(bb:add! TEXTEDITOR TEXT [REPLACE])</procedure>
503
504If {{WIDGET}} is a {{menu-bar}}, {{choice-button}} or
505{{menu-button}}, {{bb:add!}} adds a new menu with the text
506{{ITEM}} (a string), the keyboard-shortcut {{SHORTCUT}} (another string) and the callback
507{{CALLBACK}} (a procedure of no arguments).
508
509The string encoding the menu-item can include subitems, using the syntax {{foo/bar/baz}}. As many
510levels as necessary are created.
511
512The shortcut can be {{#f}} or a string describing the shortcut in one of two ways: {{[#+^]ASCII}}
513or {{[#+^]CHAR}} where a decimal value represents an ascii character (eg. 97 is the ascii for 'a'), and the
514optional prefixes enhance the value that follows. Multiple prefixes must appear in the above order.
515
516; {{#}} : Alt
517
518; {{{+}} : Shift
519
520; {{^}} : Control
521
522If {{WIDGET}} is an {{edit}},
523{{entry}} or {{text-edit}} widget, {{ITEM}}
524should be a string, which will be added to the end of the existing text.
525In case of a {{text-editor}}, the optional boolean argument {{REPLACE}}
526indicates whether the text should be inserted, or the current selection be replaced.
527
528If {{WIDGET}} is a {{list}}, the {{ITEM}} should be a string, which will added to the list
529of existing lines. The string may be prefixed by
530a {{@...}} sequence to enable special formatting:
531
532; {{@.}} : Print rest of line, don't look for more '@' signs
533
534; {{@@}} : Print rest of line starting with '@'
535
536; {{@l}} : Use a large (24 point) font
537
538; {{@m}} : Use a medium large (18 point) font
539
540; {{@s}} : Use a small (11 point) font
541
542; {{@b}} : Use a bold font
543
544; {{@i}} : Use an italic font
545
546; {{@f or @t}} :  Use a fixed-pitch font
547
548; {{@c}} : Center the line horizontally
549
550; {{@r}} : Right-justify the text
551
552; {{@B0, @B1, ... @B255}} :  Fill the backgound with indexed color
553
554; {{@C0, @C1, ... @C255}} :  Use indexed color to draw the text
555
556; {{@F0, @F1, ...}} :  Use indexed font to draw the text
557
558; {{@S1, @S2, ...}} :  Use point size n to draw the text
559
560; {{@u or @_}} : Underline the text.
561
562; {{@-}} : draw an engraved line through the middle.
563
564If {{WIDGET}} is a widget of any other type, then {{ITEM}} should be a
565child widget, which will be added with {{WIDGET}} as its parent.
566
567For {{tree}} widget {{TEXT}} can be either full path (items are
568separated with slash) or text label. If it is terminated with slash,
569the branch (rather than leaf) will be inserted. One can specify parent
570node id and position in it (default values are {{-1}} for both).  The
571{{SUBWIDGET}} is a widget that will be inserted as a node. The
572procedure returns either the unique id of the freshly inserted node or
573{{-1}} if failed.
574
575This procedure can be used to add either columns (if first
576{{CELLTEXT}} is symbol {{column}}) or cells to the {{table}} widget.
577
578===== bb:image
579
580<procedure>(bb:image X)</procedure>
581<procedure>(bb:image PTR W H D)</procedure>
582
583If {{X}} is a string, then {{bb:image}} will load an image file (if
584its format is supported by FLTK). If {{X}} is a pointer, then it is
585treated as a pointer to XPM data.  The 4-argument form of {{bb:image}}
586creates an RGB image from the data pointed to by the foreign pointer
587{{PTR}}, with width {{W}}, height {{H}} and depth {{D}}, where {{D}}
588specifies the number of color channels (1-4).
589
590===== bb:image-data
591
592<procedure>(bb:image-data IMAGE)</procedure>
593
594Returns four values: list of pointers to {{IMAGE}} data (usually one element for all formats,
595except of pixmaps), width, height and depth of the {{IMAGE}}.
596
597===== bb:remove!
598
599<procedure>(bb:remove! WIDGET [INDEX])</procedure>
600
601Removes the entry at the position {{INDEX}} from the {{list}}
602{{WIDGET}}, or all items, if index is {{#t}}. If {{widget}} is an
603image pointer, the storage occupied by the image will be released.
604For {{tree}} {{WIDGET}} the node with id {{INDEX}} will be removed.
605Destroys the widget.
606
607===== bb:set-menu-item-active!
608
609<procedure>(bb:set-menu-item-active! WIDGET INDEX FLAG)</procedure>
610
611Activates or deactivates the menu item with the index {{INDEX}} in the
612menu-bar {{WIDGET}}, depending on the boolean {{FLAG}}. Counting
613menu-items starts with 0 and every sub-menu increases the count by
614one.  Note that each sub-menu introduces an invisible extra menu-item
615that has to be counted in.
616
617===== bb:redraw
618
619<procedure>(bb:redraw WIDGET)</procedure>
620
621Redraws {{WIDGET}}.
622
623===== bb:show
624
625<procedure>(bb:show WINDOW [ARG ...])</procedure>
626
627Shows {{WINDOW}}. If {{WINDOW}} is already visible, it will be raised
628to the top.  {{ARG}}s are the options to be parsed by FLTK. By default
629the name of the executable is passed.  {{#f}} doesn't pass any
630arguments.
631
632===== bb:select-file
633
634<procedure>(bb:select-file MESSAGE PATTERN [FILENAME])</procedure>
635
636Opens a file-dialog and returns the selected filename (or {{#f}} if
637the file-selection has been canceled).  {{PATTERN}} is a file-pattern
638that is used to match filenames that can be selected. The following
639syntax is used by pattern:
640
641; {{*}} : matches any sequence of 0 or more characters.
642
643; {{?}} : matches any single character
644
645; {{[set]}} : matches any character in the set. Set can contain any single characters, or {{a-z}} to represent a range. To match {{]}} or {{-}} they must be the first characters. To match {{^}} or {{!}} they must not be the first characters.
646
647; {{[^set]}} : Matches any character not in the set.
648
649; {{[!set]}} : Matches any character not in the set.
650
651; {{{X|Y|Z}}} : Matches any one of the subexpressions literally.
652
653; {{{X,Y,Z}}} : Matches any one of the subexpressions literally.
654
655; {{\x}} : Quotes the character {{x}} so it has no special meaning.
656
657; {{x}} : All other characters must be matched exactly.
658
659{{FILENAME}} specifies the default filename, if given.
660
661===== bb:select-color
662
663<procedure>(bb:select-color [STRING])</procedure>
664<procedure>(bb:select-color COLOR [STRING])</procedure>
665
666Pops up a color-selection dialog. If {{COLOR}} is an exact integer, or
667a symbol naming one of the default colors, then the user can select a
668color index, which will then be returned. If {{COLOR}} is a
669three-element list or vector, then the user can select an RGB (or HSV)
670color. {{bb:select-color}} either returns a color value (an integer,
671encoding a color index or a packed RGB value), or {{#f}} if the
672selection dialog was closed or canceled.
673
674===== bb:rgb
675
676<procedure>(bb:rgb R [G B])</procedure>
677
678Transforms the red, green and blue components given in {{R}}, {{G}}
679and {{B}} into a color value. All components should be integers in the
680range 0 - 255. If {{G}} and {{B}} are not given, {{bb:rgb}} returns a
681list of the red, green and blue color components of the packed color
682value {{R}}.
683
684===== bb:get-input
685
686<procedure>(bb:get-input LABEL [DEFAULT])</procedure>
687
688Pops up a dialog the requests an input string. {{LABEL}} should be a
689string that will be shown in the dialog, {{DEFAULT}} is the default
690text.
691
692===== bb:group
693
694<procedure>(bb:group WIDGET THUNK)</procedure>
695
696Invokes the zero-argument procedure {{THUNK}} in a dynamic context in
697which all created widgets are added the group {{WIDGET}} (which should
698be a {{window}}, {{group}}, {{tabs}}, {{tile}}, {{pack}} or
699{{scroll}}).
700
701==== Keybindings
702
703The following is a list of keyboard and mouse shortcuts available in {{entry}} and {{edit}} widgets.
704
705; Mouse button 1 : Moves the cursor to this point. Drag selects characters.  Double click selects words.  Triple click selects all text.  Shift+click extends the selection.  When you select text it is automatically copied to the clipboard.
706
707; Mouse button 2: Insert the clipboard at the point clicked.  You can also select a region and replace it with the clipboard by selecting the region with mouse button 2.
708
709; Mouse button 3 : Currently acts like button 1.
710
711; Backspace : Deletes one character to the left, or deletes the selected region.
712
713; Enter : May cause the callback, see the {{when}} property
714
715; ^A or Home : Go to start of line.
716
717; ^B or Left : Move left
718
719; ^C : Copy the selection to the clipboard
720
721; ^D or Delete : Deletes one character to the right or deletes the selected region.
722
723; ^E or End : Go to the end of line.
724
725; ^F or Right : Move right
726
727; ^K : Delete to the end of line (next \n character) or deletes a single \n character.  These deletions are all concatenated into the clipboard.
728
729; ^N or Down : Move down ({{edit}} widget only, otherwise it moves to the next input field).
730
731; ^P or Up : Move up (for edit widgets only, otherwise it moves to the previous input field).
732
733; ^U : Delete everything.
734
735; ^V or ^Y : Paste the clipboard
736
737; ^X or ^W : Copy the region to the clipboard and delete it.
738
739; ^Z or ^_ : Undo.  This is a single-level undo mechanism, but all adjacent deletions and insertions are concatenated into a single "undo".  Often this will undo a lot more than you expected.
740
741; Shift+move : Move the cursor but also extend the selection.
742
743; RightCtrl or Compose : Start a compose-character sequence.
744
745With compose-character sequences, the next one or two keys typed define the character to insert (see [[#Character Composition Table|the table]] that follows.)
746
747For instance, to type "á" type {{[compose][a][']}} or {{[compose]['][a]}}.
748
749The character "nbsp" (non-breaking space) is typed by using {{[compose][space]}}.
750
751The single-character sequences may be followed by a space if necessary to remove ambiguity.
752For instance, if you really want to type "ª~" rather than "ã" you must type {{[compose][a][space][~]}}.
753
754The same key may be used to "quote" control characters into the text.
755If you need a {{^Q}} character you can get one by typing
756{{[compose][Control+Q]}}.
757
758X may have a key on the keyboard defined as {{XK_Multi_key}}.  If so
759this key may be used as well as the right-hand control key.  You can
760set this up with the program {{xmodmap}}.
761
762If your keyboard is set to support a foreign language you should also
763be able to type "dead key" prefix characters.  On X you will actually
764be able to see what dead key you typed, and if you then move the
765cursor without completing the sequence the accent will remain
766inserted.
767
768===== Character Composition Table
769
770<table border="1" summary="Character Composition Table">
771<tr>
772<th>Keys</th><th>Char</th>
773<th>Keys</th><th>Char</th>
774<th>Keys</th><th>Char</th>
775<th>Keys</th><th>Char</th>
776<th>Keys</th><th>Char</th>
777<th>Keys</th><th>Char</th>
778</tr>
779<tr>
780<td align="center">{{sp}}</td><td align="center"><small>nbsp</small></td>
781<td align="center">{{*}}</td><td align="center">°</td>
782<td align="center">{{` A}}</td><td align="center">À</td>
783<td align="center">{{D -}}</td><td align="center">Ð</td>
784<td align="center">{{` a}}</td><td align="center">à</td>
785<td align="center">{{d -}}</td><td align="center">ð</td>
786</tr>
787<tr>
788<td align="center">{{!}}</td><td align="center">¡</td>
789<td align="center">{{+ -}}</td><td align="center">±</td>
790<td align="center">{{' A}}</td><td align="center">Á</td>
791<td align="center">{{~ N}}</td><td align="center">Ñ</td>
792<td align="center">{{' a}}</td><td align="center">á</td>
793<td align="center">{{~ n}}</td><td align="center">ñ</td>
794</tr>
795<tr>
796<td align="center">{{%}}</td><td align="center">¢</td>
797<td align="center">{{2}}</td><td align="center">²</td>
798<td align="center">{{A ^}}</td><td align="center">Â</td>
799<td align="center">{{` O}}</td><td align="center">Ò</td>
800<td align="center">{{^ a}}</td><td align="center">â</td>
801<td align="center">{{` o}}</td><td align="center">ò</td>
802</tr>
803<tr>
804<td align="center">{{#}}</td><td align="center">£</td>
805<td align="center">{{3}}</td><td align="center">³</td>
806<td align="center">{{~ A}}</td><td align="center">Ã</td>
807<td align="center">{{' O}}</td><td align="center">Ó</td>
808<td align="center">{{~ a}}</td><td align="center">ã</td>
809<td align="center">{{' o}}</td><td align="center">ó</td>
810</tr>
811<tr>
812<td align="center">{{$}}</td><td align="center">€</td>
813<td align="center">{{'}}</td><td align="center">ÂŽ</td>
814<td align="center">{{: A}}</td><td align="center">Ä</td>
815<td align="center">{{^ O}}</td><td align="center">Ô</td>
816<td align="center">{{: a}}</td><td align="center">À</td>
817<td align="center">{{^ o}}</td><td align="center">ÃŽ</td>
818</tr>
819<tr>
820<td align="center">{{y =}}</td><td align="center">Â¥</td>
821<td align="center">{{u}}</td><td align="center">µ</td>
822<td align="center">{{* A}}</td><td align="center">Å</td>
823<td align="center">{{~ O}}</td><td align="center">Õ</td>
824<td align="center">{{* a}}</td><td align="center">Ã¥</td>
825<td align="center">{{~ o}}</td><td align="center">õ</td>
826</tr>
827<tr>
828<td align="center">{{|}}</td><td align="center">Š</td>
829<td align="center">{{p}}</td><td align="center">¶</td>
830<td align="center">{{A E}}</td><td align="center">Æ</td>
831<td align="center">{{: O}}</td><td align="center">Ö</td>
832<td align="center">{{a e}}</td><td align="center">Ê</td>
833<td align="center">{{: o}}</td><td align="center">ö</td>
834</tr>
835<tr>
836<td align="center">{{&amp;}}</td><td align="center">§</td>
837<td align="center">{{.}}</td><td align="center">·</td>
838<td align="center">{{, C}}</td><td align="center">Ç</td>
839<td align="center">{{x}}</td><td align="center">×</td>
840<td align="center">{{, c}}</td><td align="center">ç</td>
841<td align="center">{{- :}}</td><td align="center">÷</td>
842</tr>
843<tr>
844<td align="center">{{:}}</td><td align="center">š</td>
845<td align="center">{{,}}</td><td align="center">ž</td>
846<td align="center">{{E `}}</td><td align="center">È</td>
847<td align="center">{{O /}}</td><td align="center">Ø</td>
848<td align="center">{{` e}}</td><td align="center">Ú</td>
849<td align="center">{{o /}}</td><td align="center">Þ</td>
850</tr>
851<tr>
852<td align="center">{{c}}</td><td align="center">©</td>
853<td align="center">{{1}}</td><td align="center">¹</td>
854<td align="center">{{' E}}</td><td align="center">É</td>
855<td align="center">{{` U}}</td><td align="center">Ù</td>
856<td align="center">{{' e}}</td><td align="center">é</td>
857<td align="center">{{` u}}</td><td align="center">ù</td>
858</tr>
859<tr>
860<td align="center">{{a}}</td><td align="center">ª</td>
861<td align="center">{{o}}</td><td align="center">º</td>
862<td align="center">{{^ E}}</td><td align="center">Ê</td>
863<td align="center">{{' U}}</td><td align="center">Ú</td>
864<td align="center">{{^ e}}</td><td align="center">ê</td>
865<td align="center">{{' u}}</td><td align="center">ú</td>
866</tr>
867<tr>
868<td align="center">{{&lt; &lt;}}</td><td align="center">«</td>
869<td align="center">{{&gt; &gt;}}</td><td align="center">»</td>
870<td align="center">{{: E}}</td><td align="center">Ë</td>
871<td align="center">{{^ U}}</td><td align="center">Û</td>
872<td align="center">{{: e}}</td><td align="center">ë</td>
873<td align="center">{{^ u}}</td><td align="center">û</td>
874</tr>
875<tr>
876<td align="center">{{~}}</td><td align="center">¬</td>
877<td align="center">{{1 4}}</td><td align="center">Œ</td>
878<td align="center">{{` I}}</td><td align="center">Ì</td>
879<td align="center">{{: U}}</td><td align="center">Ü</td>
880<td align="center">{{` i}}</td><td align="center">ì</td>
881<td align="center">{{: u}}</td><td align="center">Ì</td>
882</tr>
883<tr>
884<td align="center">{{-}}</td><td align="center">­</td>
885<td align="center">{{1 2}}</td><td align="center">œ</td>
886<td align="center">{{' I}}</td><td align="center">Í</td>
887<td align="center">{{' Y}}</td><td align="center">Ý</td>
888<td align="center">{{' i}}</td><td align="center">í</td>
889<td align="center">{{' y}}</td><td align="center">Ü</td>
890</tr>
891<tr>
892<td align="center">{{r}}</td><td align="center">®</td>
893<td align="center">{{3 4}}</td><td align="center">Ÿ</td>
894<td align="center">{{^ I}}</td><td align="center">Î</td>
895<td align="center">{{T H}}</td><td align="center">Þ</td>
896<td align="center">{{^ i}}</td><td align="center">î</td>
897<td align="center">{{t h}}</td><td align="center">ß</td>
898</tr>
899<tr>
900<td align="center">{{_}}</td><td align="center">¯</td>
901<td align="center">{{?}}</td><td align="center">¿</td>
902<td align="center">{{: I}}</td><td align="center">Ï</td>
903<td align="center">{{s s}}</td><td align="center">ß</td>
904<td align="center">{{: i}}</td><td align="center">ï</td>
905<td align="center">{{: y}}</td><td align="center">ÿ</td>
906</tr>
907</table>
908
909==== ASCII picture interface
910
911===== bb:make-widgets
912
913<procedure>(bb:make-widgets SPEC WIDTH HEIGHT [CHARMAP])</procedure>
914
915Creates the widgets defined in the graphical representation string
916{{SPEC}} in a window of the dimensions {{WIDTH}} and {{HEIGHT}}.  The
917graphical representation string is an ASCII picture of the widget
918layout, with uppercase characters designating widget types:
919
920* {{B}} - button
921* {{C}} - check-xbox
922* {{E}} - entry
923* {{I}} - edit
924* {{N}} - counter
925* {{M}} - menu-bar
926* {{D}} - dial
927* {{S}} - slider
928* {{A}} - adjuster
929* {{L}} - list
930* {{W}} - label
931* {{O}} - radio-button
932* {{P}} - progress
933* {{T}} - tabs
934* {{F}} - glwindow
935* {{X}} - tile
936* {{G}} - group
937* {{K}} - pack
938* {{Z}} - scroll
939* {{R}} - roller
940* {{J}} - clock
941* {{V}} - live-image
942* {{H}} - choice-button
943* {{<}} - return-button
944* {{%}} - int-entry
945* {{*}} - int-entry
946* {{>}} - menu-button
947* {{Y}} - tree
948
949A widgets dimensions are computed by drawing a contguous line along
950the upper and left border, starting from the origin of the widget:
951
952  01234567890123456789
953  ....................
954  .....BBBBBBBBB......
955  .....BBBBBBBBB......
956  .....BBBBBBBBB......
957  ....................
958
959Here we would have a button at 5/1, with width 9 and height 3 (before adjusting the dimensions to the specified
960width and height of the complete layout).
961
962{{bb:make-widgets}} returns an association list of the form {{(TAG
963. WIDGET)}} which maps widget-tags to created widgets. If the optional
964argument {{CHARMAP}} (an list of lists of the form {{(ALIASCHAR CHAR
965TAG)}}) is given, then any occurrence of {{ALIASCHAR}} in the picture
966is treated as {{CHAR}}. The {{TAG}} will be returned in the widget
967a-list. If {{CHARMAP}} is not given, then the tag defaults to the
968usual widget type character.
969
970Specially delimited strings can be embedded in the widget pictures:
971
972  "STRING"
973
974Sets the {{text}} property of the widget.
975
976  |STRING|
977
978Sets the direction, box type, slider type or color of the widget. Valid values for {{STRING}} are:
979
980Direction:
981
982* v
983* h
984
985Slider type:
986
987* vfill
988* hfill
989* vnice
990* hnice
991
992box type :
993
994* no
995* flat
996* up
997* down
998* thinup
999* thindown
1000* upframe
1001* downframe
1002* thinupframe
1003* thindownframe
1004* engraved
1005* embossed
1006* engravedframe
1007* embossedframe
1008* border
1009
1010color:
1011
1012* gray
1013* black
1014* red
1015* green
1016* yellow
1017* blue
1018* magenta
1019* cyan
1020* darkred
1021* darkgreen
1022* darkyellow
1023* darkblue
1024* darkmagenta
1025* darkcyan
1026* white
1027
1028  'STRING, ...'
1029
1030Adds items to a {{list}} widget.
1031
1032  #STRING#
1033
1034{{STRING}} should be the name of an image file (as understood by {{bb:image}}).
1035
1036  :STRING:
1037
1038{{STRING}} should be the name of a global variable holding a callback,
1039or an expression evaulating to a procedure or name.
1040
1041==== SXML Interface
1042
1043===== bb:render
1044
1045<procedure>(bb:render SXML)</procedure>
1046
1047Creates the widgets defined by the
1048[[http://okmij.org/ftp/Scheme/xml.html|SXML]] representation in
1049{{SXML}}.  Each element represents a widget where the tag specifies a
1050widget type (as in {{bb:make-widget}}).  Element attributes represent
1051widget properties. Attribute-value strings are transformed according
1052to the following mapping:
1053
1054  x y width height spacing maximum minimum x-position y-position text-size
1055
1056Numeric strings. {{x}}, {{y}}, {{width}} and {{height}} may also be
1057specified as offsets given as strings prefixed with {{+}} or {{-}}, or
1058percentages given as strings suffixed with {{%}}.
1059
1060  color text-color selection-color
1061
1062A string of the form {{#RRGGBB}} or a color name
1063
1064  resizable visible focus modal read-only valid-context
1065
1066Anything different from the string {{no}} means true.
1067
1068  resizable-widget
1069
1070an element id.
1071
1072  when
1073
1074A comma-separated list of indicator-names
1075
1076Anything else is either treated as a numeric string or (if not a valid
1077number) as a symbolic property value.  Note that attribute values may
1078also be of other types than strings. The content of an SXML element
1079will be used as the {{text}} property value of the created widget, if
1080given.
1081
1082Elements may have any number of additional attributes. The attribute
1083{{id}} can be used to identify elements.
1084
1085A child widget will have the dimensions of it's parent, if no
1086{{width}} and/or {{height}} attributes are given.
1087
1088===== bb:element?
1089
1090<procedure>(bb:element? X)</procedure>
1091
1092Returns {{#t}} if {{X}} is an element, or {{#f}} otherwise.
1093
1094===== Element accessors
1095
1096<procedure>(bb:element-widget ELEMENT)</procedure>
1097<procedure>(bb:element-parent ELEMENT)</procedure>
1098<procedure>(bb:element-children ELEMENT)</procedure>
1099<procedure>(bb:element-id ELEMENT)</procedure>
1100<procedure>(bb:element-tag ELEMENT)</procedure>
1101<procedure>(bb:element-content ELEMENT)</procedure>
1102<procedure>(bb:element-attributes ELEMENT)</procedure>
1103
1104Accessor procedures for element slots. Parent is an element or {{#f}}
1105(if its the root element).  Children is a list of child
1106elements. Widget is the widget represented by this element. Id and tag
1107are symbols.  Attributes is a property list mapping attribute symbols
1108to values. Content is a string.
1109
1110===== bb:find-element
1111
1112<procedure>(bb:find-element ID [ROOT])</procedure>
1113
1114Searches the element with the id {{ID}}, starting from parent element
1115{{ROOT}}, or the value of {{(bb:root-element)}} if not given. If no
1116element with this id can be found {{#f}} is returned.
1117
1118===== bb:find-widget
1119
1120<procedure>(bb:find-widget ID [ROOT])</procedure>
1121
1122Equivalent to {{(bb:element-widget (bb:find-element ID ROOT))}}
1123
1124===== bb:root-element
1125
1126<parameter>(bb:root-element [ELEMENT])</parameter>
1127
1128Parameter holding the current root element.
1129
1130=== Examples
1131
1132<enscript highlight=scheme>
1133(use bb)
1134
1135(bb:init)
1136
1137(define w (bb:make-widget 'window 200 100))
1138
1139(bb:group
1140 w
1141 (lambda ()
1142   (let ([lbl (bb:make-widget 'label 200 100)])
1143     (set! (bb:property lbl 'box) 'engraved-box)
1144     (set! (bb:property lbl 'text-size) 32)
1145     (set! (bb:property lbl 'text-font) 'times-bold-italic)
1146     (set! (bb:property lbl 'text) "Hello, World") ) ) )
1147
1148(bb:show w)
1149
1150;An alternative, simpler way of doing the above:
1151;
1152;(bb:render
1153; '(window (@ (width 200) (height 100))
1154;         (label (@ (box engraved-box) (text-size 32) (text-font times-bold-italic))
1155;                "Hello, World")))
1156
1157(bb:run)
1158</enscript>
1159
1160A very simple shell:
1161
1162<enscript highlight=scheme>
1163(require-extension extras posix srfi-17 bb)
1164
1165(bb:init)
1166
1167(define width 300)
1168(define height 150)
1169
1170(define w (bb:make-widget 'window width height))
1171
1172(define str #<<EOF
1173LLLLLLLLLLLLLJJJJJJJ
1174LLLLLLLLLLLLLJJJJJJJ
1175LLLLLLLLLLLLLJJJJJJJ
1176EEEEEEEEEEEEEEEEEEEE
1177EOF
1178)
1179
1180(define widgets
1181  (bb:group
1182   w
1183   (lambda ()
1184     (bb:make-widgets str width height) ) ) )
1185
1186(define lst (cdr (assq #\L widgets)))
1187(define entry (cdr (assq #\E widgets)))
1188
1189(set! (bb:property entry 'callback)
1190  (lambda ()
1191    (let ([cmd (bb:property entry 'text)])
1192      (bb:add! lst (string-append "@i@." cmd))
1193      (set! (bb:property entry 'text) "")
1194      (with-input-from-pipe
1195       cmd
1196       (lambda ()
1197         (let loop ()
1198           (let ([ln (read-line)])
1199             (unless (eof-object? ln)
1200               (bb:add! lst (string-append "@." ln))
1201               (loop) ) ) ) ) ) ) ) )
1202
1203(bb:show w)
1204(bb:run)
1205</enscript>
1206
1207A simple "notes" application:
1208
1209<enscript highlight=scheme>
1210(use utils srfi-17 bb)
1211
1212(bb:init)
1213
1214(define (switch-note)
1215  (let ([item (bb:property item-list 'value)])
1216    (when (> item 0)
1217      (let ([note (list-ref all-notes (sub1 item))])
1218        (note-hidden?-set! note #f)
1219        (bb:show (note-window note)) ) ) ) )
1220
1221(bb:render
1222 `(window (@ (width 200) (height 300) (resizable) (id w) (resizable-widget lst))
1223          (menu-bar (@ (height 30) (id m)))
1224          (list (@ (y 30) (width 200) (height 270) (id lst) (callback switch-note))) ) )
1225
1226(define item-list (bb:find-widget 'lst))
1227(define menu-bar (bb:find-widget 'm))
1228(define notes-window (bb:find-widget 'w))
1229(define default-color 'yellow)
1230(define all-notes '())
1231
1232(define-record note window edit title color hidden?)
1233
1234(define (note-hider note)
1235  (lambda ()
1236    (note-hidden?-set! note #t)
1237    (set! (bb:property (note-window note) 'visible) #f) ) )
1238
1239(define (add-note . title)
1240  (let* ([name (:optional title (->string (gensym 'note)))]
1241         [x (random 600)]
1242         [y (random 400)]
1243         [w (bb:make-widget 'window x y 200 150)]
1244         [e (bb:group w (lambda () (bb:make-widget 'edit 0 0 200 150)))]
1245         [note (make-note w e name default-color #f)] )
1246    (set! (bb:property w 'resizable) #t)
1247    (set! (bb:property w 'resizable-widget) e)
1248    (set! (bb:property e 'color) default-color)
1249    (set! (bb:property w 'callback) (note-hider note))
1250    (bb:show w)
1251    (bb:add! item-list (sprintf "@.~A" name))
1252    (set! all-notes (append all-notes (list note))) ) )
1253
1254(define (choose-color)
1255  (and-let* ([col (bb:select-color default-color)])
1256    (set! default-color col) ) )
1257
1258(define notesfile (make-pathname (getenv "HOME") ".bbnotes"))
1259
1260(define (load-notes . file)
1261  (with-input-from-file (:optional file notesfile)
1262    (lambda ()
1263      (match (read)
1264        [(x y w h)
1265         (set! (bb:property notes-window 'x) x)
1266         (set! (bb:property notes-window 'y) y)
1267         (set! (bb:property notes-window 'width) w)
1268         (set! (bb:property notes-window 'height) h) ] )
1269      (let loop ()
1270        (match (read)
1271          [(? eof-object?) #f]
1272          [(title color pos text hidden?)
1273           (let* ([w (apply bb:make-widget 'window pos)]
1274                  [e (bb:group w (lambda () (apply bb:make-widget 'edit 0 0 (cddr pos))))]
1275                  [note (make-note w e title color hidden?)] )
1276             (set! (bb:property e 'color) color)
1277             (set! (bb:property w 'resizable) #t)
1278             (set! (bb:property w 'resizable-widget) e)
1279             (set! (bb:property w 'text) title)
1280             (set! (bb:property w 'callback) (note-hider note))
1281             (bb:add! e text)
1282             (unless hidden? (bb:show w))
1283             (set! all-notes (append all-notes (list note)))
1284             (bb:add! item-list (string-append "@." title))
1285             (loop) ) ] ) ) ) ) )
1286
1287(define (save-notes . file)
1288  (with-output-to-file (:optional file notesfile)
1289    (lambda ()
1290      (write (map (cut bb:property notes-window <>) '(x y width height)))
1291      (newline)
1292      (for-each
1293       (lambda (note)
1294         (let ([w (note-window note)]
1295               [e (note-edit note)] )
1296           (write
1297            (list
1298             (note-title note)
1299             (note-color note)
1300             (list (bb:property w 'x) (bb:property w 'y) (bb:property w 'width) (bb:property w 'height))
1301             (bb:property e 'text)
1302             (note-hidden? note) ) )
1303           (newline) ) )
1304       all-notes) ) ) )
1305
1306(define (change-title)
1307  (let ([i (bb:property item-list 'value)])
1308    (when (> i 0)
1309      (let* ([note (list-ref all-notes (sub1 i))]
1310             [title (bb:get-input "Enter new title" (note-title note))] )
1311        (set! (bb:property (note-window note) 'text) title)
1312        (note-title-set! note title)
1313        (update-list) ) ) ) )
1314
1315(define (update-list)
1316  (bb:remove! item-list #t)
1317  (for-each (lambda (note) (bb:add! item-list (string-append "@." (note-title note)))) all-notes) )
1318
1319(define (change-color)
1320  (let ([i (bb:property item-list 'value)])
1321    (when (> i 0)
1322      (let* ([note (list-ref all-notes (sub1 i))]
1323             [col (bb:select-color (note-color note))] )
1324        (set! (bb:property (note-edit note) 'color) col)
1325        (bb:redraw (note-edit note))
1326        (note-color-set! note col) ) ) ) )
1327
1328(define (fini)
1329  (save-notes)
1330  (exit) )
1331
1332(set! (bb:property notes-window 'callback) fini) ; when ESC is pressed
1333
1334(bb:add! menu-bar "File/Quit" fini "^q")
1335(bb:add! menu-bar "Notes/New" add-note "^n")
1336(bb:add! menu-bar "Notes/Set default color..." choose-color)
1337(bb:add! menu-bar "Change/Title..." change-title)
1338(bb:add! menu-bar "Change/Color..." change-color)
1339
1340(bb:show notes-window)
1341
1342(when (file-exists? notesfile) (load-notes))
1343
1344(bb:run)
1345</enscript>
1346
1347Event handlers usage:
1348
1349<enscript highlight=scheme>
1350(use srfi-17 bb)
1351
1352(bb:init)
1353
1354(define w (bb:make-widget 'window 200 100))
1355(define e (bb:make-widget 'edit 5 5 150 25))
1356(set! (bb:property e 'callback) (lambda () (display "edit was changed") (newline) ) )
1357(set! (bb:property e 'when) 'changed)
1358(set! (bb:property e 'handler)
1359  (lambda (e)
1360    (case e
1361      [(move)
1362       (printf "mouse was moved over edit at (~A, ~A)~%" (bb:event 'x) (bb:event 'y))
1363       #t]
1364      [(push)
1365       (printf "mouse was clicked on edit, clicks = 1 + ~A~%" (bb:event 'clicks))
1366       (set! (bb:event 'clicks) 0)
1367       (printf "clicks after setting: ~A~%" (bb:event 'clicks))
1368       #t]
1369      [(keydown)
1370       (printf "key was pressed: ~A~%" (bb:event 'key))
1371       -1]
1372      [else -1] ) ; pass other events to the base class
1373    ) )
1374
1375(bb:show w)
1376(bb:run)
1377</enscript>
1378
1379=== Changelog
1380
1381* 1.28 fixed problem on 64-bit machines (thanks to Jim Pryor)
1382* 1.27 ported to CHICKEN 4
1383* 1.26 Added {{bb:select-directory}} [contributed by Joerg Wittenberger]
1384* 1.25 Changed widget_type macro to use cast to long [Thanks to Ignaz Peter Hochgemuth]
1385* 1.24 Uses lowercase file extension for FLU header [Thanks to Juergen Lorenz]
1386* 1.23 Setting properties could invoke callbacks and needed a {{___safe}} marker [Thanks to Nico Amtsberg]
1387* 1.22 Used proper extension for included FLTK headers [Thanks to Matthew Welland]
1388* 1.21 Added missing {{(use easyffi)}} [Thanks to Juergen Lorenz]
1389* 1.20 Added proper check for FLTK installation [reported by Brandon Van Every]
1390* 1.19 Adapted to externalized easyffi
1391* 1.18 Removed "_s" suffix from references to library-files [Thanks to Markus H&uuml;lsmann]
1392* 1.17 Added {{label-color}}, {{label-font}} and {{label-size}} properties.
1393* 1.16 Fixed several bugs in property-getting code [Thanks to John]; {{bb:add!}} can replace current selection in text-editor widget
1394* 1.15 Fixed bug in {{bb:show}} [Thanks to Markus H&uuml;smann]
1395* 1.14 The implicit-exit-handler didn't take previously installed exit-handlers into account (which could give problems when embedding); Fixed bug in {{bb:show}} related to embedded use
1396* 1.13 Invalid property values could result in unbound recursion
1397* 1.12 The {{selection}} property of a {{text-editor}} widgets can be set, now; Some bugfixes in callback-removal
1398* 1.11 {{bb:remove!}} allows completely clearing a list widget by passing the index {{#t}}; destroying widgets removes all registered callbacks from children as well.
1399* 1.10 Fixed setting {{text-color}} for the {{tree}} widget. Added support for Windows.
1400* 1.9 {{bb:remove!}} allows destroying all types of widgets; {{bb:show}} had to be marked as callback; fixed bugs in selection-retrieval and special key-event handling
1401* 1.8 Sergey Khorev added the {{table}} and {{html-view}} widgets
1402* 1.7 Added {{text-editor}} widget
1403* 1.6 Fixed bug in the setup script
1404* 1.5 More widgets added by Sergey
1405* 1.4 Sergey Khorev added support for custom event handlers
1406* 1.3 Adapted to new FFI macro names
1407* 1.2 Converted to new extension scheme; fixed a bug in {{bb:get}} (Thanks to Daniel B. Faken)
1408* 1.1 Added {{bb:init}} and {{bb:set-menu-item-active!}} and fixed a bug in {{bb:property}}. It is now required to call {{bb:init}} before using any other bb procedure.
1409* 1.0
Note: See TracBrowser for help on using the repository browser.