source: project/wiki/iup-tutor @ 36409

Last change on this file since 36409 was 32504, checked in by svnwiki, 4 years ago

Anonymous wiki edit for IP [127.0.0.1]: Fix spelling

File size: 40.8 KB
Line 
1[[toc:]]
2
3== Tutorial on the Iup Graphical User Interface toolkit
4
5Iup is a small and easy to use GUI toolkit, originally written in pure
6C, but accompanied by an optional resource language LED, to make life
7easier. It has later been ported to Lua and other scripting languages,
8and nowadays it is considered Lua's native GUI-toolkit. Thanks to
9[[/users/thomas-chust|Thomas Chust]] CHICKEN and Racket ports exist as well.
10
11Unfortunately, the documentation is somewhat scattered in the internet:
12
13[[/eggref/4/iup|CHICKEN port of the Iup GUI library]]
14
15[[http://www.chust.org/fossils/iup/doc/trunk/api/main.wiki|the official API docs]].
16
17[[http://www.tecgraf.puc-rio.br/iup/|IUP "portable user interface" GUI library]].
18
19Hence you need to consult the original C documentation very often. So it
20seems appropriate to start with an example (Hello World, you guess it)
21showing how a C program is translated to Scheme. This way you'll become
22comfortable writing Scheme programs while using the original C
23documentation. But before that let me recapitulate some design
24principles of Iup.
25
26=== Iup's design principles
27
28Iup programs consist of dialogs, which communicate with each other. A
29dialog can contain only one widget, usually a container, which in turn
30can contain other widgets, containers included. For widgets to be
31visible, they must transparently be mapped to native widgets of the
32system: Gtk+ or Motif under X11, WinAPI under Windows or Cocoa with a
33third party extension under Mac OS X.
34
35The mapping happens only once a dialog is shown. Destroying a dialog
36after its use destroys the included widgets as well. Hence, only dialogs
37need to be destroyed at the end of a program.
38
39Like other GUI-toolkits, interaction with the user happens within a main
40loop. But what makes Iup stand out of the crowd are two principles:
41
42First: No widget is ever positioned with explicit coordinates.
43Everything is done logically by nesting containers and positioning
44widgets like fill. This facilitates matters considerably.
45
46Second: The appearance of all widgets and dialogs is controlled by
47attributes, their behaviour by callbacks. This makes the library small.
48
49
50In C, attribute names as well as values are strings and attribute setting
51is a separate step from object construction. In Scheme a little more
52syntactic sugar is available: Attribute names are usually keywords, which
53can be passed directly to widget constructors. Attribute values can be
54almost anything you want, including handles and anything that can sensibly
55be converted to a string.
56
57When you get or set an attribute explicitly, you can also use strings or
58symbols as attribute names. Getting is done (in Scheme) by the attribute
59function, setting by the attribute-set! procedure or a generalized set!,
60i.e. either by
61
62(attribute-set! widget name: val) or (set! (attribute widget name:) val)
63
64whichever you prefer. The same applies to callbacks, which are get and
65set by callback and callback-set! respectively.
66
67In Scheme's Iup callbacks are functions of one or more arguments,
68including self, which can return a symbol, for example 'close, to close a
69dialog, or 'default, to keep it open. In C, on the other hand, the
70return values are #define'd integers.
71
72=== Hello World
73
74Let's start with the most trivial version, in C and in CHICKEN:
75
76==== hello0.c
77
78<enscript highlight="c">
79#include <iup.h>
80#include <stdlib.h>
81
82int main (int argc, char *argv[]) {
83  IupOpen(&argc, &argv);
84  IupShow(IupDialog(IupLabel ("Hello, world!")));
85  IupMainLoop();
86  IupClose();
87  return 0;
88}
89</enscript>
90
91==== hello0.scm
92
93<enscript highlight="c">
94(use iup)
95(show (dialog (label "Hello, world!")))
96(main-loop)
97(exit 0)
98</enscript>
99
100Note, that initializing and closing iup disappears in CHICKEN, since it
101is done when inporting iup. Note also, that the CHICKEN names are much
102friendlier than the C ones: CHICKEN's module system makes Iup prefixes
103superfluous, they can be added, if needed, with appropriate import
104clauses.
105
106Now a version which shows, how to use attributes and callbacks, again in
107C, and in two CHICKEN versions. The first is almost a literal
108translation of the C version, the second a condensed version, where all
109attributes are set in the creation process.
110
111==== hello1.c
112
113<enscript highlight="c">
114#include <iup.h>
115#include <stdlib.h>
116
117int exit_cb (void) {
118  return IUP_CLOSE;
119}
120
121int main (int argc, char *argv[]) {
122
123  // declare widgets
124  Ihandle *btn, *lbl, *vb, *dlg;
125
126  // initialize iup
127  IupOpen(&argc, &argv);
128 
129  // create widgets and set their attributes
130  btn=IupButton("&Ok", "");
131  IupSetCallback(btn,"ACTION", (Icallback) exit_cb);
132  IupSetAttribute(btn, "EXPAND", "Yes");
133  IupSetAttribute(btn, "TIP", "Exit button");
134 
135  lbl=IupLabel("Hello,world!");
136
137  vb=IupVbox(lbl, btn, NULL);
138  IupSetAttribute(vb, "GAP", "10");
139  IupSetAttribute(vb, "MARGIN", "10x10");
140  IupSetAttribute(vb, "ALIGNMENT", "ACENTER");
141
142  dlg=IupDialog(vb);
143  IupSetAttribute(dlg, "TITLE", "Hello");
144
145  // Map widgets and show dialog
146  IupShow(dlg);
147
148  // Wait for user interaction
149  IupMainLoop();
150
151  // Clean up
152  IupDestroy(dlg);
153  IupClose();
154  return EXIT_SUCCESS;
155}
156</enscript>
157
158==== hello11.scm
159
160Here is a translation to Scheme ...
161
162<enscript highlight="scheme">
163(use iup)
164
165(define (cb-exit self) 'close)
166
167(define btn (button))
168(set! (callback btn action:) cb-exit)
169(set! (attribute btn title:) '&Ok)
170(set! (attribute btn expand:) 'Yes)
171(set! (attribute btn tip:) "Close button")
172
173(define lbl (label "Hello World!"))
174
175(define vb (vbox lbl btn))
176(attribute-set! vb gap: 10)
177(attribute-set! vb margin: '15x15)
178(attribute-set! vb alignment: 'ACENTER)
179
180(define dlg (dialog vb))
181(attribute-set! dlg title: 'Hello)
182
183(show dlg)
184(main-loop)
185(destroy! dlg)
186(exit 0)
187</enscript>
188
189Note, how the upper-case C-names of attributes change to lower-case
190CHICKEN-keywords (by the way, CHICKEN-keywords can be either written with
191a trailing colon or a leading hash-colon, but I prefere the former,
192which looks nicer).
193
194Note also, that attribute values can be numbers or symbols as well. The
195Iup convention is to use "Yes" and "No" as boolean values. In Scheme you
196can use symbols as well.  And last, but not least, note the tips:
197attribute, which defines tooltips, and the ampersand in the button's
198title, which defines a shortcut, Alt+underlined-character, to execute
199the callback.
200
201==== hello12.scm
202
203... and here a condensed version.
204
205<enscript highlight="scheme">
206(use iup)
207
208(define dlg
209  (dialog
210    (vbox
211      (label "Hello, World!")
212      (button title: '&Ok
213              expand: 'Yes
214              tip: "Close button"
215              action: (lambda (self) 'close))
216      gap: 10
217      alignment: 'ACENTER
218      margin: '15x15)
219    title: 'IUP))
220
221(show dlg)
222(main-loop)
223(destroy! dlg)
224(exit 0)
225</enscript>
226
227Note, how smoothly the indentation reflects the logical representation
228of the dialog.
229
230=== The LED resource language
231
232The condensed version above can be almost literally transformed into a
233LED resource file, which can be either loaded into a C program or a
234Scheme program. Those resources are interpreted at runtime, so that even
235in a compiled program the resource can be changed afterwards, provided
236the identifiers remain consistent.
237
238The form of a LED-declaration looks as follows
239
240<enscript highlight="c">
241widget=widget-type[attribute-name=attribute-value, ...](arg, ...)
242</enscript>
243
244where the attributes' names and values are written without enclosing
245quotes, but interpreted as strings.
246
247Here is an example and its use in CHICKEN.
248
249==== hello.led
250
251<enscript highlight="c">
252btn = button[TIP = "Close window", EXPAND = Yes]("&Ok", 0)
253
254dlg = dialog[TITLE = Hello](
255            vbox[GAP = 10, MARGIN = 15x15, ALIGNMENT = ACENTER](
256                label("Hello world!"),
257                btn))
258</enscript>
259
260==== hello13.scm
261
262<enscript highlight="scheme">
263(use iup)
264
265(load/led "hello.led")
266
267(callback-set! (handle-ref "btn")
268               action: (lambda (self) 'close))
269
270(define dlg (handle-ref "dlg"))
271
272(show dlg)
273(main-loop)
274(destroy! dlg)
275(exit 0)
276</enscript>
277
278Note, that the LED-import is done via load/led and the identification
279of LED-names with CHICKEN-variables via handle-ref.
280
281Note also, that btn must have a name, because
282we need to set the callback, which can not be a string.
283
284You can compile hello13.scm with csc and change hello.led afterwards.
285Try it out and play with some attributes, for example, remove the
286EXPAND attribute from btn and set it for label, ...
287
288=== Visualize your design
289
290Iup has two dialogs which you can use to visualize your design,
291layout-dialog and element-properties-dialog. They can be used to inspect
292what you have already done and what's still available. For example, if
293you replace the line (show dlg) by (show (layout-dialog dlg)) you can
294see the tree structure of your design and inspect the properties of each
295widget by right-clicking on it and choosing the appropriate menu-item of
296the popped-up context-menu.
297
298The layout-dialog menu has an export item as well, whith which you can
299export your design to C, Lua or LED. Of course, for CHICKEN only the
300LED export is of any value. But be warned, the dialog is not stable and
301exporting will crash the program very often, in particular, if the
302target LED file doesn't already exist. But if the export makes the
303program crash while overwriting  an existing LED file, your work is
304lost.  So, you better won't use layout-dialog to create your design, but
305only to inspect it. That's not that bad, because visual design doesn't
306help much in a language like Scheme, where the syntax-tree of a program
307is already visible in its source code, and a good text editor is much
308faster than a visual editor ....
309
310The other dialog, element-properties-dialog, can conveniently be used
311for documentation purposes, by applying it to each existing widget with
312attributes set to the most primitive values. This is done in the
313following example.
314
315==== inspector.scm
316
317When writing an Iup application, you have always the problem, that you
318don't know in advance, what are the available widgets and what are the
319registered attributes and callbacks of each widget. To help with
320problems like this you can, of course, study the original documentation,
321and as a method of last resort you have to do that. But for a quick
322overview you can start the program "inspector" below. It's rather ugly.
323But that's not important here.
324
325Note, that there are no libraries iup-web, iup-pplot and iup-glcanvas.
326They are all contained in the iup library. Hence we have to separate the
327installation of the library iup from the import of its sublibraries.
328
329<enscript highlight="scheme">
330(require-library srfi-4 iup)
331(import srfi-4 iup iup-web iup-pplot iup-glcanvas)
332
333(define (popup dlg . args)
334  (apply show dlg #:modal? 'yes args)
335  (destroy! dlg))
336
337(define (properties ih)
338  (popup (element-properties-dialog ih))
339  'default)
340
341(define dlg
342  (dialog
343    (vbox
344      (hbox ; headline
345        (fill)
346        (frame (label " Inspect control and dialog classes "
347                      fontsize: 15))
348        (fill)
349        margin: '0x0)
350
351      (label "")
352      (label "Dialogs" fontsize: 12)
353      (hbox
354        (button "dialog"
355                action: (lambda (self) (properties (dialog (vbox)))))
356        (button "color-dialog"
357                action: (lambda (self) (properties (color-dialog))))
358        (button "file-dialog"
359                action: (lambda (self) (properties (file-dialog))))
360        (button "font-dialog"
361                action: (lambda (self) (properties (font-dialog))))
362        (button "message-dialog"
363                action: (lambda (self) (properties (message-dialog))))
364        (fill)
365        margin: '0x0)
366      (hbox
367        (button "layout-dialog"
368                action: (lambda (self) (properties (layout-dialog))))
369        (button "element-properties-dialog"
370                action: (lambda (self)
371                          (properties
372                            (element-properties-dialog (create 'user)))))
373        (fill)
374        margin: '0x0)
375
376      (label "")
377      (label "Composition widgets" fontsize: 12)
378      (hbox
379        (button "fill"
380                action: (lambda (self) (properties (fill))))
381        (button "hbox"
382                action: (lambda (self) (properties (hbox))))
383        (button "vbox"
384                action: (lambda (self) (properties (vbox))))
385        (button "zbox"
386                action: (lambda (self) (properties (zbox))))
387        (button "radio"
388                action: (lambda (self) (properties (radio (vbox)))))
389        (button "normalizer"
390                action: (lambda (self) (properties (normalizer))))
391        (button "cbox"
392                action: (lambda (self) (properties (cbox))))
393        (button "sbox"
394                action: (lambda (self) (properties (sbox (vbox)))))
395        (button "split"
396                action: (lambda (self) (properties (split (vbox) (vbox)))))
397        (fill)
398        margin: '0x0)
399
400      (label "")
401      (label "Standard widgets" fontsize: 12)
402      (hbox
403        (button "button"
404                action: (lambda (self) (properties (button))))
405        (button "canvas"
406                action: (lambda (self) (properties (canvas))))
407        (button "frame"
408                action: (lambda (self) (properties (frame))))
409        (button "label"
410                action: (lambda (self) (properties (label))))
411        (button "listbox"
412                action: (lambda (self) (properties (listbox))))
413        (button "progress-bar"
414                action: (lambda (self) (properties (progress-bar))))
415        (button "spin"
416                action: (lambda (self) (properties (spin))))
417        (fill)
418        margin: '0x0)
419      (hbox
420        (button "tabs"
421                action: (lambda (self) (properties (tabs))))
422        (button "textbox"
423                action: (lambda (self) (properties (textbox))))
424        (button "toggle"
425                action: (lambda (self) (properties (toggle))))
426        (button "treebox"
427                action: (lambda (self) (properties (treebox))))
428        (button "valuator"
429                action: (lambda (self) (properties (valuator ""))))
430        (fill)
431        margin: '0x0)
432
433      (label "")
434      (label "Additional widgets" fontsize: 12)
435      (hbox
436        (button "cells"
437                action: (lambda (self) (properties (cells))))
438        (button "color-bar"
439                action: (lambda (self) (properties (color-bar))))
440        (button "color-browser"
441                action: (lambda (self) (properties (color-browser))))
442        (button "dial"
443                action: (lambda (self) (properties (dial ""))))
444        (button "matrix"
445                action: (lambda (self) (properties (matrix))))
446        (fill)
447        margin: '0x0)
448      (hbox
449        (button "pplot"
450                action: (lambda (self) (properties (pplot))))
451        (button "glcanvas"
452                action: (lambda (self) (properties (glcanvas))))
453        (button "web-browser"
454                action: (lambda (self) (properties (web-browser))))
455        (fill)
456        margin: '0x0)
457
458      (label "")
459      (label "Menu widgets" fontsize: 12)
460      (hbox
461        (button "menu"
462                action: (lambda (self) (properties (menu))))
463        (button "menu-item"
464                action: (lambda (self) (properties (menu-item))))
465        (button "menu-separator"
466                action: (lambda (self) (properties (menu-separator))))
467        (fill)
468        margin: '0x0)
469
470      (label "")
471      (label "Images" fontsize: 12)
472      (hbox
473        (button "image/palette"
474                action: (lambda (self)
475                          (properties
476                            (image/palette 1 1 (u8vector->blob (u8vector 0))))))
477        (button "image/rgb"
478                action: (lambda (self)
479                          (properties
480                            (image/rgb 1 1 (u8vector->blob (u8vector 0))))))
481        (button "image/rgba"
482                action: (lambda (self)
483                          (properties
484                            (image/rgba 1 1 (u8vector->blob (u8vector 0))))))
485        (button "image/file"
486                action: (lambda (self)
487                          (properties
488                            ;; same attributes as image/palette
489                            (image/palette 1 1 (u8vector->blob (u8vector 0))))))
490                            ;; needs a file in current directory
491                            ;(image/file "chicken.ico")))) ; ok
492                            ;(image/file "chicken.png")))) ; doesn't work
493        (fill)
494        margin: '0x0)
495
496      (label "")
497      (label "Other widgets" fontsize: 12)
498      (hbox
499        (button "clipboard"
500                action: (lambda (self) (properties (clipboard))))
501        (button "timer"
502                action: (lambda (self) (properties (timer))))
503        (button "spinbox"
504                action: (lambda (self) (properties (spinbox (vbox)))))
505        (fill)
506        margin: '0x0)
507
508      (fill)
509      (button "E&xit"
510              expand: 'horizontal
511              action: (lambda (self) 'close))
512      )
513    margin: '15x15
514    title: "Iup inspector"))
515
516(show dlg)
517(main-loop)
518(exit 0)
519</enscript>
520
521When you compile this program and use it, you will note, that some
522attributes can be inherited. That means, that all children of an object
523inherit those attributes. To override this, you must set those
524attributes in the children anew (look at the margin: attribute above).
525Moreover, you'll notice that there are tabs not only on attributes and
526callbacks, but on a hash-table as well.  This is how Iup handles class
527extension. If you want a widget to have an attribute "foo", you can
528simply use (attribute-set! widget "foo" "value").  Those hash-table
529attributes are inherited as well. By the way, you are not obliged, to
530use strings only in their definition.
531 
532=== Porting some examples from the Iup Distribution
533
534Now we'll show, how some predefined widgets work. For that we'll port
535some of the C-examples.
536
537==== fill.scm
538
539The following dialog shows, how different positions of the fill widget
540change the dialog's appearance.
541
542<enscript highlight="scheme">
543(use iup)
544
545;;; Create frame with left aligned button
546(define frame-left
547  (frame
548    (hbox
549      (button title: '&Left
550              tip: "Left button"
551              action: (lambda (self)
552                        (print "Stay in with Left button")
553                        'default))
554      (fill))))
555(set! (attribute frame-left title:) "Left aligned")
556
557;;; Create frame with centered button
558(define frame-center
559  (frame
560    (hbox
561      (fill)
562      (button title: '&Center
563              tip: "Central button"
564              action: (lambda (self)
565                        (print "Way out with Central button")
566                        'close))
567      (fill))))
568(attribute-set! frame-center title: "Centered")
569
570;;; Create frame with right aligned button
571(define frame-right
572  (frame
573    (hbox
574      (fill)
575      (button title: '&Right
576              tip: "Right button"
577              action: (lambda (self)
578                        (print "Way out with Right button")
579                        'close)))
580    title: "Right aligned"))
581
582; Note, that callbacks should return a symbol.
583; Only the symbol 'close of the action: callbacks closes the dialog!
584
585;;; Create dialog with these three frames
586(define dlg
587  (dialog
588    (vbox
589      frame-left
590      frame-center
591      frame-right)))
592(set! (attribute dlg size:) 120)
593(set! (attribute dlg title:) 'Fill)
594
595(show dlg)
596(main-loop)
597(destroy! dlg)
598(exit 0)
599</enscript>
600
601==== hbox.scm
602
603This dialog shows, how horizontal boxes within vertical ones work.
604
605<enscript highlight="scheme">
606(use iup)
607
608(define dlg
609  (dialog
610    (vbox
611      (frame
612        (hbox (fill)
613              (button "1" "" size: "30x30")
614              (button "2" "" size: "30x40")
615              (button "3" "" size: "30x50")
616              (fill)
617              alignment: "ATOP"
618              gap: 10
619              size: 200)
620        title: "alignment: ATOP gap: 10 size: 200"
621        gap: 10
622        size: 200)
623      (frame
624        (hbox (fill)
625              (button "1" "" size: "30x30")
626              (button "2" "" size: "30x40")
627              (button "3" "" size: "30x50")
628              (fill)
629              alignment: "ACENTER"
630              gap: 20)
631        title: "alignment: ACENTER gap: 20"
632        gap: 20)
633      (frame
634        (hbox (fill)
635              (button "1" "" size: "30x30")
636              (button "2" "" size: "30x40")
637              (button "3" "" size: "30x50")
638              (fill)
639              alignment: "ABOTTOM"
640              size: 150)
641        title: "alignment: ABOTTOM size: 150"
642        size: 150))
643    title: "Hbox"))
644
645(show dlg x: 'center y: 'center)
646(main-loop)
647(destroy! dlg)
648</enscript>
649
650==== menu.scm
651
652Now a dialog with a menu and submenus, one of whose items call a
653predefined message-dialog.
654
655<enscript highlight="scheme">
656(require-library iup)
657(import iup iup-dialogs)
658
659(define item-open (menu-item "&Open"))
660
661(define item-save (menu-item "&Save"))
662
663(define item-undo (menu-item "&Undo" active: "NO"))
664
665(define item-exit (menu-item "E&xit"))
666(set! (callback item-exit action:)
667      (lambda (self) 'close))
668
669(define file-menu
670  (menu item-open
671        item-save
672        (menu-separator)
673        item-undo
674        item-exit))
675
676(define item-about (menu-item "&About"))
677(define (about-cb self)
678  (show (message-dialog value: "Information goes here ...") modal?: #t)
679  'default)
680(callback-set! item-about action: about-cb)
681
682(define help-menu
683  (menu item-about))
684
685(define mnu
686  (menu (menu-item "&File" file-menu)
687        (menu-item "&Help" help-menu)))
688;(set! (handle-name mnu) "mymenu")
689
690(define dlg (dialog (canvas "")))
691(set! (attribute dlg menu:) mnu);"mymenu")
692(set! (attribute dlg title:) "Menu")
693
694(show dlg)
695(main-loop)
696(exit 0)
697</enscript>
698
699Note, that the underlined characters behave differently in menus and
700submenus. In the former they execute their callbacks with the Alt
701prefix, in the latter without.
702
703Note also, that predefined dialogs can only be shown with the modal?:
704attribute set.
705
706==== filedlg.scm
707
708Now we use two predefined dialogs, file-dialag and message-dialog. You
709should note, that they are mapped to gtk-dialogs!
710
711<enscript highlight="scheme">
712(use iup)
713
714(define (popup dlg . args)
715  (apply show dlg #:modal? #t  args)
716  (destroy dlg))
717
718(define dlg (file-dialog title: "File save"
719                         dialogtype: 'SAVE
720                         filter: "*.led"
721                         filterinfo: "Iup resource file"))
722
723(popup dlg x: 'center y: 'center)
724
725(let ((status (attribute dlg status:)))
726  (cond
727    ((string=? status "1")
728     (popup
729       (message-dialog value: (string-append  "New File: "
730                                              (attribute dlg value:)))))
731    ((string=? status "0")
732     (popup
733       (message-dialog value: (string-append  "File already exists: "
734                                              (attribute dlg value:)))))
735    ((string=? status "-1")
736     (popup
737       (message-dialog value: "File-dialog: Operation Canceled")))))
738
739(destroy! dlg)
740(exit 0)
741</enscript>
742
743Note, that the status: attribute of the file-dialog is a string!
744
745==== multiline.scm
746
747Now, we'll show how widgets within a dialog can communicate whith each
748other. The trick is, that Iup can reference widgets by name, or, to be
749more precise, by string name. You have seen this in the LED example
750above: In LED a widget is named by a string and constructed by the LED
751interpreter. To use it in Scheme, you reference the widget proper
752from its name via handle-ref. This can be done without LED as well. But
753then you must give the widget a string name via handle-name-set! or the
754generalized version (set! (handle-name widget) name).
755
756The following dialog contains two textboxes, one of them multiline, a
757dropdown listbox and some buttons, allowing to get or set the multiline
758attributes. Please take note, how handle-ref and handle-name is used.
759
760<enscript highlight="scheme">
761(use iup)
762
763(define (message title value)
764  (show (message-dialog title: title value: value) #:modal? #t))
765
766;; setter and getter
767;; widgets are referenced by name
768(define (set-attribute keyword)
769  (let (
770    (msg (sprintf "Attribute ~A set with value ~A"
771                  keyword (attribute single value:)))
772    (multi (handle-ref "multi"))
773    (single (handle-ref "single"))
774    )
775    (attribute-set! multi keyword (attribute single value:))
776    (message "Set attribute" msg)
777    'default))
778
779(define (get-attribute keyword)
780  (let (
781    (msg (sprintf "Attribute ~A get with value ~A"
782                  keyword (attribute multi keyword)))
783    (multi (handle-ref "multi"))
784    (single (handle-ref "single"))
785    )
786    (attribute-set! single value: (attribute multi keyword))
787    (message "Get attribute" msg)
788    'default))
789
790;; callback generator
791(define (cb keyword)
792  (lambda (self)
793    (let ((lb (handle-ref "lb")))
794      (if (eqv? (string->number (attribute lb value:)) 1)
795        (set-attribute keyword)
796        (get-attribute keyword))
797      'default)))
798
799;; buttons
800(define btn-append
801  (button title: '&Append
802          action: (cb append:)))
803
804(define btn-insert
805  (button title: '&Insert
806          action: (cb insert:)))
807
808(define btn-border
809  (button title: '&Border
810          action: (cb border:)))
811
812(define btn-caret
813  (button title: '&Caret
814          action: (cb caret:)))
815
816(define btn-readonly
817  (button title: '&Readonly
818          action: (cb readonly:)))
819
820(define btn-selection
821  (button title: '&Selection
822          action: (cb selection:)))
823
824(define btn-selectedtext
825  (button title: 'Selected&text
826          action: (cb selectedtext:)))
827
828(define btn-nc
829  (button title: '&Nc
830          action: (cb nc:)))
831
832(define btn-value
833  (button title: '&Value
834          action: (cb value:)))
835
836;; other widgets
837(define lb (listbox #:1 'set #:2 'get value: 1 dropdown: 'Yes))
838(define multi (textbox expand: 'Yes multiline: 'Yes))
839(define single (textbox expand: 'horizontal))
840
841;; name those other widgets, so that they can be referenced by name
842(set! (handle-name lb) "lb")
843(set! (handle-name multi) "multi")
844(set! (handle-name single) "single")
845
846;; the dialog
847(define dlg
848  (dialog (vbox multi
849                (hbox lb
850                      single)
851                (hbox btn-append btn-insert btn-border btn-caret
852                      btn-readonly btn-selection)
853                (hbox btn-selectedtext btn-nc btn-value))
854          title: "Multiline example"
855          size: 'HALFxQUARTER))
856
857(show dlg x: 'center y: 'center)
858(main-loop)
859(destroy! dlg)
860(exit 0)
861</enscript>
862
863There is one caveat in the listbox: The lines must be denoted with
864prefixed keyword notation, 1: will not work, for example!
865
866==== progressbar.scm
867
868Now a dialog with a progressbar and a timer as well as some pixmap
869images for the control buttons. The latter are constructed with
870image/palette, which accepts two dimension parameters and a blob with
871the pixmap data. The color of each pixel is described by a number and
872translated by that very number attribute to an rgb-string.
873
874<enscript highlight="scheme">
875(use iup srfi-4)
876
877;; button images
878
879(define pause-img
880  (image/palette 22 22
881    (u8vector->blob
882      (u8vector
883        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
884        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
885        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
886        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
887        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
888        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
889        2 2 2 2 2 2 2 1 1 2 2 1 1 2 2 2 2 2 2 2 2 2
890        2 2 2 2 2 2 2 1 1 2 2 1 1 2 2 2 2 2 2 2 2 2
891        2 2 2 2 2 2 2 1 1 2 2 1 1 2 2 2 2 2 2 2 2 2
892        2 2 2 2 2 2 2 1 1 2 2 1 1 2 2 2 2 2 2 2 2 2
893        2 2 2 2 2 2 2 1 1 2 2 1 1 2 2 2 2 2 2 2 2 2
894        2 2 2 2 2 2 2 1 1 2 2 1 1 2 2 2 2 2 2 2 2 2
895        2 2 2 2 2 2 2 1 1 2 2 1 1 2 2 2 2 2 2 2 2 2
896        2 2 2 2 2 2 2 1 1 2 2 1 1 2 2 2 2 2 2 2 2 2
897        2 2 2 2 2 2 2 1 1 2 2 1 1 2 2 2 2 2 2 2 2 2
898        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
899        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
900        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
901        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
902        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
903        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
904        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2))
905    #:1 "0 0 0"
906    #:2 "220 218 213"))
907
908(define play-img
909  (image/palette 22 22
910    (u8vector->blob
911      (u8vector
912        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
913        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
914        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
915        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
916        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
917        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
918        2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2
919        2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2
920        2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2
921        2 2 2 2 2 2 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2
922        2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2
923        2 2 2 2 2 2 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2
924        2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2
925        2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2
926        2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2
927        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
928        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
929        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
930        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
931        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
932        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
933        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2))
934    #:1 "0 0 0"
935    #:2 "220 218 213"))
936 
937(define reset-img
938  (image/palette 22 22
939    (u8vector->blob
940      (u8vector
941        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
942        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
943        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
944        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
945        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
946        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
947        2 2 2 2 1 1 2 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2
948        2 2 2 2 1 1 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2
949        2 2 2 2 1 1 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2
950        2 2 2 2 1 1 2 2 1 1 1 1 1 1 1 1 2 2 2 2 2 2
951        2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2
952        2 2 2 2 1 1 2 2 1 1 1 1 1 1 1 1 2 2 2 2 2 2
953        2 2 2 2 1 1 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2
954        2 2 2 2 1 1 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2
955        2 2 2 2 1 1 2 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2
956        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
957        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
958        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
959        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
960        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
961        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
962        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2))
963    #:1 "0 0 0"
964    #:2 "220 218 213"))
965
966(define decelerate-img
967  (image/palette 22 22
968    (u8vector->blob
969      (u8vector
970        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
971        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
972        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
973        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
974        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
975        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
976        2 2 2 2 2 2 2 2 2 1 2 2 2 2 1 2 2 2 2 2 2 2
977        2 2 2 2 2 2 2 2 1 1 2 2 2 1 1 2 2 2 2 2 2 2
978        2 2 2 2 2 2 2 1 1 1 2 2 1 1 1 2 2 2 2 2 2 2
979        2 2 2 2 2 2 1 1 1 1 2 1 1 1 1 2 2 2 2 2 2 2
980        2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2
981        2 2 2 2 2 2 1 1 1 1 2 1 1 1 1 2 2 2 2 2 2 2
982        2 2 2 2 2 2 2 1 1 1 2 2 1 1 1 2 2 2 2 2 2 2
983        2 2 2 2 2 2 2 2 1 1 2 2 2 1 1 2 2 2 2 2 2 2
984        2 2 2 2 2 2 2 2 2 1 2 2 2 2 1 2 2 2 2 2 2 2
985        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
986        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
987        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
988        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
989        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
990        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
991        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2))
992    #:1 "0 0 0"
993    #:2 "220 218 213"))
994
995(define forward-img
996  (image/palette 22 22
997    (u8vector->blob
998      (u8vector
999        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1000        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1001        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1002        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1003        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1004        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1005        2 2 2 2 2 2 2 1 2 2 2 2 1 2 2 2 2 2 2 2 2 2
1006        2 2 2 2 2 2 2 1 1 2 2 2 1 1 2 2 2 2 2 2 2 2
1007        2 2 2 2 2 2 2 1 1 1 2 2 1 1 1 2 2 2 2 2 2 2
1008        2 2 2 2 2 2 2 1 1 1 1 2 1 1 1 1 2 2 2 2 2 2
1009        2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2
1010        2 2 2 2 2 2 2 1 1 1 1 2 1 1 1 1 2 2 2 2 2 2
1011        2 2 2 2 2 2 2 1 1 1 2 2 1 1 1 2 2 2 2 2 2 2
1012        2 2 2 2 2 2 2 1 1 2 2 2 1 1 2 2 2 2 2 2 2 2
1013        2 2 2 2 2 2 2 1 2 2 2 2 1 2 2 2 2 2 2 2 2 2
1014        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1015        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1016        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1017        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1018        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1019        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1020        2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2))
1021    #:1 "0 0 0"
1022    #:2 "220 218 213"))
1023
1024(define speed 0.01)
1025
1026;; button callbacks
1027
1028(define (ok-cb self) 'close)
1029
1030(define (idle-cb self)
1031  (set! (attribute progressbar value:)
1032        (+ (string->number (attribute progressbar value:)) speed))
1033        ; will internally be transformed to a string
1034  (if (>= (string->number (attribute progressbar value:)) 1)
1035    (set! (attribute progressbar value:) 0))
1036  'default)
1037
1038(define (pause-cb self)
1039  (if (string= (attribute tmr run:) "YES")
1040    (begin
1041      (attribute-set! tmr run: 'no) ; internally transformed to "NO"
1042      (attribute-set! pause-btn image: pause-img))
1043    (begin
1044      (attribute-set! tmr run: 'yes) ; internally transformed to "YES"
1045      (attribute-set! pause-btn image: play-img)))
1046  'default)
1047
1048(define (reset-cb self)
1049  (attribute-set! progressbar value: 0)
1050  'default)
1051
1052(define (accelerate-cb self)
1053  (set! speed (* 2 speed))
1054  (if (> speed 1.0) (set! speed 1.0))
1055  'default)
1056
1057(define (decelerate-cb self)
1058  (set! speed (/ speed 2))
1059  'default)
1060
1061;; buttons
1062
1063(define reset-btn
1064  (button "&Reset"
1065          action: reset-cb
1066          tip: "Reset timer"
1067          image: reset-img))
1068
1069(define pause-btn
1070  (button "&Pause"
1071          action: pause-cb
1072          tip: "Pause timer"
1073          image: play-img))
1074
1075(define accelerate-btn
1076  (button "&Accelerate"
1077          action: accelerate-cb
1078          tip: "Accelerate timer"
1079          image: forward-img))
1080
1081(define decelerate-btn
1082  (button "&Decelerate"
1083          action: decelerate-cb
1084          tip: "Decelerate timer"
1085          image: decelerate-img))
1086
1087(define ok-btn
1088  (button "&OK"
1089          action: ok-cb
1090          tip: "Close window"
1091          expand: 'yes))
1092
1093;; timer
1094
1095(define tmr (timer time: 100 action-cb: idle-cb))
1096(attribute-set! tmr run: 'yes) ; doesn't work in constructor
1097; 'yes or any of the values 1, 'true, "TRUE", #t ... will internally
1098; be transformed to "YES"
1099
1100;; progressbar
1101
1102(define progressbar
1103  (progress-bar value: "0.34"
1104                ;dashed: 'yes ; doesn't work
1105                expand: 'yes))
1106
1107;; dialog
1108
1109(define dlg
1110  (dialog
1111    (vbox progressbar
1112          (hbox
1113            (fill)
1114            pause-btn
1115            reset-btn
1116            decelerate-btn
1117            accelerate-btn
1118            (fill))
1119          (fill)
1120          (hbox
1121            (fill)
1122            ok-btn
1123            (fill)))
1124    title: 'Progressbar
1125    resize: 'no))
1126
1127;; run
1128
1129(show dlg)
1130(main-loop)
1131(destroy! dlg)
1132(exit 0)
1133</enscript>
1134
1135==== webbrowser.scm
1136
1137Now an example which shows how mighty iup-web is, a CHICKEN
1138implementation of the webkit engine. With some lines of code we can
1139write a fully functional webbrowser. But there is one caveat with it:
1140For reasons I don't understand, the program will crash unless you load
1141libiupweb.so via the LD_PRELOAD environment variable.
1142
1143Another Warning: Running this file in the interpreter with the readline
1144module loaded will cause a segfault. To be on the safe side use csi -n.
1145
1146<enscript highlight="scheme">
1147(require-library iup)
1148(import iup iup-web data-structures)
1149
1150;;; webbrowser callbacks
1151
1152(define (on-history self)
1153  (let (
1154    (back (attribute (handle-ref "dlg-web") backcount:))
1155    (fwrd (attribute (handle-ref "dlg-web") forwardcount:))
1156    )
1157    (print "History items")
1158    (let loop ((i (if (string? back) (- (string->number back)) 0)))
1159      (unless (zero? i)
1160        (printf "Backward ~a: ~a~%"
1161                i (attribute (handle-ref "dlg-web")
1162                             (string->keyword (sprintf "itemhistory~a" i))))
1163        (loop (+ i 1))))
1164    (printf "Current ~a: ~a~%"
1165            0 (attribute (handle-ref "dlg-web") itemhistory0:))
1166    (let ((fwd (if (string? fwrd) (string->number fwrd) 0)))
1167      (let loop ((i 1))
1168        (unless (> i fwd)
1169          (printf "Forward ~a: ~a~%"
1170                  i (attribute (handle-ref "dlg-web")
1171                               (string->keyword (sprintf "itemhistory~a" i))))
1172          (loop (+ i 1)))))
1173    'default))
1174
1175(define (on-navigation self url)
1176  (print "web-browser navigate-cb: url " url)
1177  (if (substring-index "download" url)
1178    'ignore
1179    'default))
1180
1181(define (on-error self url)
1182  (print "web-browser error-cb: url " url)
1183  'default)
1184     
1185(define (on-completion self); url)
1186  (print "web-browser completed-cb: value: " (attribute self value:)); url)
1187  (attribute-set! (handle-ref "dlg-listbox") insertitem1:
1188                  (attribute self value:))
1189  (attribute-set! (handle-ref "dlg-listbox") value:
1190                  (attribute self value:))
1191  'default)
1192; note, that the documentation required two arguments, but the attribute
1193; completed-cb: accepted only one.
1194     
1195(define (on-newwindow self url)
1196  (print "web-browser newwindow-cb: url " url)
1197  (attribute-set! self value: url)
1198  'default)
1199
1200;;; button callbacks
1201
1202(define (on-back self)
1203  (attribute-set! (handle-ref "dlg-web") backforward: -1)
1204  'default)
1205     
1206(define (on-forward self)
1207  (attribute-set! (handle-ref "dlg-web") backforward: 1)
1208  'default)
1209     
1210(define (on-stop self)
1211  (attribute-set! (handle-ref "dlg-web") stop: 'no)
1212  'default)
1213     
1214(define (on-reload self)
1215  (attribute-set! (handle-ref "dlg-web") reload: 'no)
1216  'default)
1217     
1218(define (on-load self)
1219  (attribute-set! (handle-ref "dlg-web") value:
1220                  (attribute (handle-ref "dlg-listbox") value:))
1221  'default)
1222
1223(define (on-search self)
1224  (attribute-set! (handle-ref "dlg-web") value:
1225                  "https://eu.ixquick.com")
1226  'default)
1227
1228(define (on-home self)
1229  (attribute-set! (handle-ref "dlg-web") value:
1230                  "http://www.call-cc.org")
1231  'default)
1232
1233;;; listbox callbacks
1234
1235(define (on-valuechanged self)
1236  (print "listbox valuechanged-cb: value: "(attribute self value:))
1237  (attribute-set! (handle-ref "dlg-web") value:
1238                  (attribute self value:))
1239  'default)
1240
1241(define (on-dropdown self state)
1242  (print "listbox dropdown-cb: state " state " value: " (attribute self value:))
1243  'default)
1244
1245(define (on-action self text item state)
1246  (print "listbox action: text " text " item " item " state " state)
1247  (if (= state 1)
1248    (attribute-set! (handle-ref "dlg-web") value: text))
1249  'default)
1250
1251(define (on-key self key)
1252  (print "listbox k-any: key " key)
1253  (if (= key (char->integer #\return))
1254    (attribute-set! (handle-ref "dlg-web") value:
1255                    (attribute self value:)))
1256  'continue)
1257
1258;;;;;;;;;;;;;;;;; WebBrowserTest
1259
1260;(define dlg-textbox
1261;  (textbox value: "http://wiki.call-cc.org";www.tecgraf.puc-rio.br/iup"
1262;           expand: 'horizontal))
1263;(handle-name-set! dlg-textbox "dlg-textbox")
1264
1265(define dlg-listbox
1266  (listbox value: "http://www.tecgraf.puc-rio.br/iup";call-cc.org"
1267           expand: 'horizontal
1268           dropdown: 'yes
1269           editbox: 'yes
1270           #:1 "http://api.call-cc.org"
1271           action: on-action
1272           k-any: on-key
1273           dropdown-cb: on-dropdown
1274           ;valuechanged-cb: on-valuechanged
1275           ;edit-cb: on-edit
1276           ))
1277(handle-name-set! dlg-listbox "dlg-listbox")
1278
1279(define dlg-web
1280  (web-browser value: (attribute dlg-listbox value:)
1281               ;value: (attribute dlg-textbox value:)
1282               newwindow-cb: on-newwindow
1283               navigate-cb: on-navigation
1284               error-cb: on-error
1285               completed-cb: on-completion))
1286                             ;(lambda (self)
1287                             ;  (on-completion self (attribute self value:)))))
1288                             ;  ;; wrapper replaces the C typecast (Icallback)
1289(handle-name-set! dlg-web "dlg-web")
1290
1291(define dlg
1292  (dialog
1293    (vbox
1294      (hbox
1295        (button "&Home" action: on-home)
1296        (button "&Back" action: on-back)
1297        (button "&Forward" action: on-forward)
1298        (button "&Load" action: on-load)
1299        (button "&Reload" action: on-reload)
1300        (button "S&top" action: on-stop)
1301        (button "H&istory" action: on-history)
1302        (button "&Search" action: on-search)
1303        (fill)
1304        (button "E&xit" action: (lambda (self) 'close))
1305        )
1306      dlg-listbox
1307      dlg-web)
1308    rastersize: '800x600
1309    title: 'WebBrowser))
1310    ;defaultenter: btn-load
1311    ;margin: '10x10
1312    ;gap: 10))
1313
1314(show dlg)
1315(main-loop)
1316(destroy! dlg)
1317(exit 0)
1318</enscript>
1319
1320=== Concluding remark
1321
1322All these examples show, that Iup is really easy to use ...
1323
1324== Author
1325
1326[[/users/juergen-lorenz|Juergen Lorenz]]
1327
1328== Initial version
1329
1330Nov 25, 2011
1331
1332== Last updated
1333
1334Apr 04, 2012
Note: See TracBrowser for help on using the repository browser.