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

Last change on this file since 32241 was 32241, checked in by felix winkelmann, 6 years ago

removed some call/cc.org links

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