source: project/wiki/iup-tutor @ 25662

Last change on this file since 25662 was 25662, checked in by juergen, 9 years ago

iup-tutor: gauge-led added

File size: 25.6 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
80#include <iup.h>
81#include <stdlib.h>
82
83int main (int argc, char *argv[]) {
84  IupOpen(&argc, &argv);
85  IupShow(IupDialog(IupLabel ("Hello, world!")));
86  IupMainLoop();
87  IupClose();
88  return 0;
89}
90
91</enscript>
92
93==== hello0.scm
94
95<enscript highlight="c">
96
97(use iup)
98(show (dialog (label "Hello, world!")))
99(main-loop)
100(exit 0)
101
102</enscript>
103
104Note, that initializing and closing iup disappears in Chicken, since it
105is done when inporting iup. Note also, that the Chicken names are much
106friendlier than the C ones: Chicken's module system makes Iup prefixes
107superfluous, they can be added, if needed, with appropriate import
108clauses.
109
110Now a version which shows, how to use attributes and callbacks, again in
111C, and in two Chicken versions. The first is almost a literal
112translation of the C version, the second a condensed version, where all
113attributes are set in the creation process.
114
115==== hello1.c
116
117<enscript highlight="c">
118
119#include <iup.h>
120#include <stdlib.h>
121
122int exit_cb (void) {
123  return IUP_CLOSE;
124}
125
126int main (int argc, char *argv[]) {
127
128  // declare widgets
129  Ihandle *btn, *lbl, *vb, *dlg;
130
131  // initialize iup
132  IupOpen(&argc, &argv);
133 
134  // create widgets and set their attributes
135  btn=IupButton("&Ok", "");
136  IupSetCallback(btn,"ACTION", (Icallback) exit_cb);
137  IupSetAttribute(btn, "EXPAND", "Yes");
138  IupSetAttribute(btn, "TIP", "Exit button");
139 
140  lbl=IupLabel("Hello,world!");
141
142  vb=IupVbox(lbl, btn);
143  IupSetAttribute(vb, "GAP", "10");
144  IupSetAttribute(vb, "MARGIN", "10x10");
145  IupSetAttribute(vb, "ALIGNMENT", "ACENTER");
146
147  dlg=IupDialog(vb);
148  IupSetAttribute(dlg, "TITLE", "Hello");
149
150  // Map widgets and show dialog
151  IupShow(dlg);
152
153  // Wait for user interaction
154  IupMainLoop();
155
156  // Clean up
157  IupDestroy(dlg);
158  IupClose();
159  return EXIT_SUCCESS;
160}
161
162</enscript>
163
164==== hello11.scm
165
166Here is a translation to Scheme ...
167
168<enscript highlight="scheme">
169
170(use iup)
171
172(define (cb-exit self) 'close)
173
174(define btn (button))
175(set! (callback btn action:) cb-exit)
176(set! (attribute btn title:) '&Ok)
177(set! (attribute btn expand:) 'Yes)
178(set! (attribute btn tip:) "Close button")
179
180(define lbl (label "Hello World!"))
181
182(define vb (vbox lbl btn))
183(attribute-set! vb gap: 10)
184(attribute-set! vb margin: '15x15)
185(attribute-set! vb alignment: 'ACENTER)
186
187(define dlg (dialog vb))
188(attribute-set! dlg title: 'Hello)
189
190(show dlg)
191(main-loop)
192(destroy! dlg)
193(exit 0)
194
195</enscript>
196
197Note, how the upper-case C-names of attributes change to lower-case
198Chicken-keywords (by the way, Chicken-keywords can be either written with
199a trailing colon or a leading hash-colon, but I prefere the former,
200which looks nicer).
201
202Note also, that attribute values can be numbers or symbols as well. The Iup convention is to use "Yes" and "No" as boolean values. In Scheme you can use symbols as well.
203And last, but not least, note the tips: attribute, which defines
204tooltips, and the ampersand in the button's title, which defines a
205shortcut, Alt+underlined-character, to execute the callback.
206
207==== hello12.scm
208
209... and here a condensed version.
210
211<enscript highlight="scheme">
212
213(use iup)
214
215(define dlg
216  (dialog
217    (vbox
218      (label "Hello, World!")
219      (button title: '&Ok
220              expand: 'Yes
221              tip: "Close button"
222              action: (lambda (self) 'close))
223      gap: 10
224      alignment: 'ACENTER
225      margin: '15x15)
226    title: 'IUP))
227
228(show dlg)
229(main-loop)
230(destroy! dlg)
231(exit 0)
232
233</enscript>
234
235Note, how smoothly the indentation reflects the logical representation
236of the dialog.
237
238=== The LED resource language
239
240The condensed version above can be almost literally transformed into a
241LED resource file, which can be either loaded into a C program or a
242Scheme program. Those resources are interpreted at runtime, so that even
243in a compiled program the resource can be changed afterwards, provided
244the identifiers remain consistent.
245
246The form of a LED-declaration looks as follows
247
248<enscript highlight="c">
249
250widget=widget-type[attribute-name=attribute-value, ...](arg, ...)
251
252</enscript>
253
254where the attributes' names and values are written without enclosing
255quotes, but interpreted as strings.
256
257Here is an example and its use in Chicken.
258
259==== hello.led
260
261<enscript highlight="c">
262
263btn = button[TIP = "Close window", EXPAND = Yes]("&Ok", 0)
264
265dlg = dialog[TITLE = Hello](
266            vbox[GAP = 10, MARGIN = 15x15, ALIGNMENT = ACENTER](
267                label("Hello world!"),
268                btn))
269
270</enscript>
271
272==== hello13.scm
273
274<enscript highlight="scheme">
275
276(use iup)
277
278(load/led "hello.led")
279
280(callback-set! (handle-ref "btn")
281               action: (lambda (self) 'close))
282
283(define dlg (handle-ref "dlg"))
284
285(show dlg)
286(main-loop)
287(destroy! dlg)
288(exit 0)
289
290</enscript>
291
292Note, that the LED-import is done via load/led and the identification
293of LED-names with Chicken-variables via handle-ref.
294
295Note also, that btn must have a name, because
296we need to set the callback, which can not be a string.
297
298You can compile hello13.scm with csc and change hello.led afterwards.
299Try it out and play with some attributes, for example, remove the
300EXPAND attribute from btn and set it for label, ...
301
302=== Porting some examples from the Iup Distribution
303
304Now we'll show, how some predefined widgets work. For that we'll port
305some of the C-examples.
306
307==== fill.scm
308
309The following dialog shows, how different positions of the fill widget
310change the dialog's appearance.
311
312<enscript highlight="scheme">
313
314(use iup)
315
316;;; Create frame with left aligned button
317(define frame-left
318  (frame
319    (hbox
320      (button title: '&Left
321              tip: "Left button"
322              action: (lambda (self)
323                        (print "Stay in with Left button")
324                        'default))
325      (fill))))
326(set! (attribute frame-left title:) "Left aligned")
327
328;;; Create frame with centered button
329(define frame-center
330  (frame
331    (hbox
332      (fill)
333      (button title: '&Center
334              tip: "Central button"
335              action: (lambda (self)
336                        (print "Way out with Central button")
337                        'close))
338      (fill))))
339(attribute-set! frame-center title: "Centered")
340
341;;; Create frame with right aligned button
342(define frame-right
343  (frame
344    (hbox
345      (fill)
346      (button title: '&Right
347              tip: "Right button"
348              action: (lambda (self)
349                        (print "Way out with Right button")
350                        'close)))
351    title: "Right aligned"))
352
353; Note, that callbacks should return a symbol.
354; Only the symbol 'close of the action: callbacks closes the dialog!
355
356;;; Create dialog with these three frames
357(define dlg
358  (dialog
359    (vbox
360      frame-left
361      frame-center
362      frame-right)))
363(set! (attribute dlg size:) 120)
364(set! (attribute dlg title:) 'Fill)
365
366(show dlg)
367(main-loop)
368(destroy! dlg)
369(exit 0)
370
371</enscript>
372
373==== hbox.scm
374
375This dialog shows, how horizontal boxes within vertical ones work.
376
377<enscript highlight="scheme">
378
379(use iup)
380
381(define dlg
382  (dialog
383    (vbox
384      (frame
385        (hbox (fill)
386              (button "1" "" size: "30x30")
387              (button "2" "" size: "30x40")
388              (button "3" "" size: "30x50")
389              (fill)
390              alignment: "ATOP"
391              gap: 10
392              size: 200)
393        title: "alignment: ATOP gap: 10 size: 200"
394        gap: 10
395        size: 200)
396      (frame
397        (hbox (fill)
398              (button "1" "" size: "30x30")
399              (button "2" "" size: "30x40")
400              (button "3" "" size: "30x50")
401              (fill)
402              alignment: "ACENTER"
403              gap: 20)
404        title: "alignment: ACENTER gap: 20"
405        gap: 20)
406      (frame
407        (hbox (fill)
408              (button "1" "" size: "30x30")
409              (button "2" "" size: "30x40")
410              (button "3" "" size: "30x50")
411              (fill)
412              alignment: "ABOTTOM"
413              size: 150)
414        title: "alignment: ABOTTOM size: 150"
415        size: 150))
416    title: "Hbox"))
417
418(show dlg x: 'center y: 'center)
419(main-loop)
420(destroy! dlg)
421
422</enscript>
423
424==== menu.scm
425
426Now a dialog with a menu and submenus, one of whose items call a
427predefined message-dialog.
428
429<enscript highlight="scheme">
430
431(use iup iup-dialogs)
432
433(define item-open (menu-item "&Open"))
434
435(define item-save (menu-item "&Save"))
436
437(define item-undo (menu-item "&Undo" active: "NO"))
438
439(define item-exit (menu-item "E&xit"))
440(set! (callback item-exit action:)
441      (lambda (self) 'close))
442
443(define file-menu
444  (menu item-open
445        item-save
446        (menu-separator)
447        item-undo
448        item-exit))
449
450(define item-about (menu-item "&About"))
451(define (about-cb self)
452  (show (message-dialog value: "Information goes here ...") modal?: #t)
453  'default)
454(callback-set! item-about action: about-cb)
455
456(define help-menu
457  (menu item-about))
458
459(define mnu
460  (menu (menu-item "&File" file-menu)
461        (menu-item "&Help" help-menu)))
462;(set! (handle-name mnu) "mymenu")
463
464(define dlg (dialog (canvas "")))
465(set! (attribute dlg menu:) mnu);"mymenu")
466(set! (attribute dlg title:) "Menu")
467
468(show dlg)
469(main-loop)
470(exit 0)
471
472</enscript>
473
474Note, that the underlined characters behave differently in menus and
475submenus. In the former they execute their callbacks with the Alt
476prefix, in the latter without.
477
478Note also, that predefined dialogs can only be shown with the modal?:
479attribute set.
480
481==== filedlg.scm
482
483Now we use two predefined dialogs, file-dialag and message-dialog. You
484should note, that they are mapped to gtk-dialogs!
485
486<enscript highlight="scheme">
487
488(use iup)
489
490(define (popup dlg . args)
491  (apply show dlg #:modal? #t  args)
492  (destroy dlg))
493
494(define dlg (file-dialog title: "File save"
495                         dialogtype: 'SAVE
496                         filter: "*.led"
497                         filterinfo: "Iup resource file"))
498
499(popup dlg x: 'center y: 'center)
500
501(let ((status (attribute dlg status:)))
502  (cond
503    ((string=? status "1")
504     (popup
505       (message-dialog value: (string-append  "New File: "
506                                              (attribute dlg value:)))))
507    ((string=? status "0")
508     (popup
509       (message-dialog value: (string-append  "File already exists: "
510                                              (attribute dlg value:)))))
511    ((string=? status "-1")
512     (popup
513       (message-dialog value: "File-dialog: Operation Canceled")))))
514
515(destroy! dlg)
516(exit 0)
517
518</enscript>
519
520Note, that the status: attribute of the file-dialog is a string!
521
522==== multiline.scm
523
524Now, we'll show how widgets within a dialog can communicate whith each
525other. The trick is, that Iup can reference widgets by name, or, to be
526more precise, by string name. You have seen this in the LED example
527above: In LED a widget is named by a string and constructed by the LED
528interpreter. To use it in Scheme, you reference the widget proper
529from its name via handle-ref. This can be done without LED as well. But
530then you must give the widget a string name via handle-name-set! or the
531generalized version (set! (handle-name widget) name).
532
533The following dialog contains two textboxes, one of them multiline, a
534dropdown listbox and some buttons, allowing to get or set the multiline
535attributes. Please take note, how handle-ref and handle-name is used.
536
537<enscript highlight="scheme">
538
539(use iup)
540
541(define (message title value)
542  (show (message-dialog title: title value: value) #:modal? #t))
543
544;; setter and getter
545;; widgets are referenced by name
546(define (set-attribute keyword)
547  (let (
548    (msg (sprintf "Attribute ~A set with value ~A"
549                  keyword (attribute single value:)))
550    (multi (handle-ref "multi"))
551    (single (handle-ref "single"))
552    )
553    (attribute-set! multi keyword (attribute single value:))
554    (message "Set attribute" msg)
555    'default))
556
557(define (get-attribute keyword)
558  (let (
559    (msg (sprintf "Attribute ~A get with value ~A"
560                  keyword (attribute multi keyword)))
561    (multi (handle-ref "multi"))
562    (single (handle-ref "single"))
563    )
564    (attribute-set! single value: (attribute multi keyword))
565    (message "Get attribute" msg)
566    'default))
567
568;; callback generator
569(define (cb keyword)
570  (lambda (self)
571    (let ((lb (handle-ref "lb")))
572      (if (eqv? (string->number (attribute lb value:)) 1)
573        (set-attribute keyword)
574        (get-attribute keyword))
575      'default)))
576
577;; buttons
578(define btn-append
579  (button title: '&Append
580          action: (cb append:)))
581
582(define btn-insert
583  (button title: '&Insert
584          action: (cb insert:)))
585
586(define btn-border
587  (button title: '&Border
588          action: (cb boarder:)))
589
590(define btn-caret
591  (button title: '&Caret
592          action: (cb caret:)))
593
594(define btn-readonly
595  (button title: '&Readonly
596          action: (cb readonly:)))
597
598(define btn-selection
599  (button title: '&Selection
600          action: (cb selection:)))
601
602(define btn-selectedtextbox
603  (button title: 'Selected&textbox
604          action: (cb selectedbox:)))
605
606(define btn-nc
607  (button title: '&Nc
608          action: (cb nc:)))
609
610(define btn-value
611  (button title: '&Value
612          action: (cb value:)))
613
614;; other widgets
615(define lb (listbox #:1 'set #:2 'get value: 1 dropdown: 'Yes))
616(define multi (textbox expand: 'Yes multiline: 'Yes))
617(define single (textbox expand: 'horizontal))
618
619;; name those other widgets, so that they can be referenced by name
620(set! (handle-name lb) "lb")
621(set! (handle-name multi) "multi")
622(set! (handle-name single) "single")
623
624;; the dialog
625(define dlg
626  (dialog (vbox multi
627                (hbox lb
628                      single)
629                (hbox btn-append btn-insert btn-border btn-caret
630                      btn-readonly btn-selection)
631                (hbox btn-selectedtextbox btn-nc btn-value))
632          title: "Multiline example"
633          size: 'HALFxQUARTER))
634
635(show dlg x: 'center y: 'center)
636(main-loop)
637(destroy! dlg)
638(exit 0)
639</enscript>
640
641There is one caveat in the listbox: The lines must be denoted with
642prefixed keyword notation, 1: will not work, for example!
643
644==== gauge-led.scm
645
646Now a dialog with a gauge and a timer, written with a led resource.
647
648Creates a gauge with 5 control buttons. The first button stops and
649starts the Gauge. The second one starts the Gauge. The third one
650reduces its speed. The fourth one increases its speed. The fifth one
651shows or hides the percentage inside the Gauge.
652
653We start with the resource:
654
655<enscript highlight="c">
656
657# play image (pause button)
658img-play = image[1="0 0 0",2="BGCOLOR"](22,22,
659  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
660 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
661 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
662 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
663 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
664 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
665 ,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2
666 ,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2
667 ,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2
668 ,2,2,2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2
669 ,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2
670 ,2,2,2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2
671 ,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2
672 ,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2
673 ,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2
674 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
675 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
676 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
677 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
678 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
679 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
680 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 )
681 
682# start image (start button)
683img-start = image[1="0 0 0",2="BGCOLOR"](22,22,
684  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
685 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
686 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
687 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
688 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
689 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
690 ,2,2,2,2,1,1,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2
691 ,2,2,2,2,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,2
692 ,2,2,2,2,1,1,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2
693 ,2,2,2,2,1,1,2,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2
694 ,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2
695 ,2,2,2,2,1,1,2,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2
696 ,2,2,2,2,1,1,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2
697 ,2,2,2,2,1,1,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,2
698 ,2,2,2,2,1,1,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2
699 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
700 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
701 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
702 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
703 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
704 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
705 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 )
706
707# rewind image (decelerate button)
708img-rewind = image[1="0 0 0",2="BGCOLOR"](22,22,
709  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
710 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
711 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
712 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
713 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
714 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
715 ,2,2,2,2,2,2,2,2,2,1,2,2,2,2,1,2,2,2,2,2,2,2
716 ,2,2,2,2,2,2,2,2,1,1,2,2,2,1,1,2,2,2,2,2,2,2
717 ,2,2,2,2,2,2,2,1,1,1,2,2,1,1,1,2,2,2,2,2,2,2
718 ,2,2,2,2,2,2,1,1,1,1,2,1,1,1,1,2,2,2,2,2,2,2
719 ,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2
720 ,2,2,2,2,2,2,1,1,1,1,2,1,1,1,1,2,2,2,2,2,2,2
721 ,2,2,2,2,2,2,2,1,1,1,2,2,1,1,1,2,2,2,2,2,2,2
722 ,2,2,2,2,2,2,2,2,1,1,2,2,2,1,1,2,2,2,2,2,2,2
723 ,2,2,2,2,2,2,2,2,2,1,2,2,2,2,1,2,2,2,2,2,2,2
724 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
725 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
726 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
727 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
728 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
729 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
730 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 )
731
732# forward image (accelerate button)
733img-forward = image[1="0 0 0",2="BGCOLOR"](22,22,
734  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
735 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
736 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
737 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
738 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
739 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
740 ,2,2,2,2,2,2,2,1,2,2,2,2,1,2,2,2,2,2,2,2,2,2
741 ,2,2,2,2,2,2,2,1,1,2,2,2,1,1,2,2,2,2,2,2,2,2
742 ,2,2,2,2,2,2,2,1,1,1,2,2,1,1,1,2,2,2,2,2,2,2
743 ,2,2,2,2,2,2,2,1,1,1,1,2,1,1,1,1,2,2,2,2,2,2
744 ,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2
745 ,2,2,2,2,2,2,2,1,1,1,1,2,1,1,1,1,2,2,2,2,2,2
746 ,2,2,2,2,2,2,2,1,1,1,2,2,1,1,1,2,2,2,2,2,2,2
747 ,2,2,2,2,2,2,2,1,1,2,2,2,1,1,2,2,2,2,2,2,2,2
748 ,2,2,2,2,2,2,2,1,2,2,2,2,1,2,2,2,2,2,2,2,2,2
749 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
750 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
751 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
752 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
753 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
754 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
755 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 )
756
757# show image (show button)
758img-show = image[1="0 0 0",2="BGCOLOR"](22,22,
759  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
760 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
761 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
762 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
763 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
764 ,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2
765 ,2,2,2,2,2,2,2,1,1,2,2,2,2,1,1,2,2,2,2,2,2,2
766 ,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2
767 ,2,2,2,2,2,1,2,2,2,1,1,1,2,2,2,2,1,2,2,2,2,2
768 ,2,2,2,2,1,2,2,2,1,1,2,2,1,2,2,2,2,1,2,2,2,2
769 ,2,2,2,1,2,2,2,2,1,1,1,2,1,2,2,2,2,2,1,2,2,2
770 ,2,2,2,2,1,2,2,2,1,1,1,1,1,2,2,2,2,1,2,2,2,2
771 ,2,2,2,2,2,1,2,2,2,1,1,1,2,2,2,2,1,2,2,2,2,2
772 ,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2
773 ,2,2,2,2,2,2,2,1,1,2,2,2,2,1,1,2,2,2,2,2,2,2
774 ,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2
775 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
776 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
777 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
778 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
779 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
780 ,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 )
781 
782start-btn = button[TIP="Reset", IMAGE=img-start]("start", 0)
783pause-btn = button[TIP="Pause", IMAGE=img-play]("pause",0)
784accelerate-btn = button[TIP="Accelerate", IMAGE=img-forward]( "accelerate", 0)
785decelerate-btn = button[TIP="Rewind", IMAGE=img-rewind]( "decelerate", 0)
786show-btn = button[TIP="Show", IMAGE=img-show]( "show", 0)
787
788gauge-name=gauge[VALUE="0.84", EXPAND=YES]()
789#gauge-name=GAUGE[VALUE="0.34", SIZE="QUARTERxEIGHTH"]()
790command-box=hbox
791(
792  fill(),
793  pause-btn,
794  start-btn,
795  decelerate-btn,
796  accelerate-btn,
797  show-btn,
798  fill())
799
800ok-btn =  button[TIP = "Close window", EXPAND = YES] ("&Ok", 0)
801
802#end-box = HBOX(ok-btn)
803end-box = HBOX(fill(), ok-btn, fill())
804
805box=VBOX
806(
807  gauge-name,
808  command-box,
809  fill(),
810  end-box
811)
812
813dlg = DIALOG[TITLE="Gauge", RESIZE=NO]
814(
815  box
816)
817
818</enscript>
819
820And now the Scheme implementation
821
822<enscript highlight="scheme">
823
824(use iup)
825
826(define speed 0.00001)
827
828;; callbacks
829
830(define (ok-cb self) 'close)
831
832(define (idle-cb self)
833  (let (
834    (value (string->number (attribute gauge-name value:)))
835    (min (string->number (attribute gauge-name min:)))
836    (max (string->number (attribute gauge-name max:)))
837    )
838    (set! (attribute gauge-name value:)
839          (number->string (+ value speed)))
840    (if (>= (string->number (attribute gauge-name value:)) max)
841      (set! (attribute gauge-name value:) min))
842    'default))
843
844(define (pause-cb self)
845  (if (not (attribute #f idle-action:))
846    (set! (callback gauge-name idle-action:) (lambda (self) (idle-cb)))
847    (set! (callback gauge-name idle-action:) #f))
848  'default)
849
850(define (start-cb self)
851  (set! (attribute gauge-name value:)
852        (attribute gauge-name min:))
853  'default)
854
855(define (accelerate-cb self)
856  (set! speed (* 2 speed))
857  (if (> speed 1.0) (set! speed 1.0))
858  'default)
859
860(define (decelerate-cb self)
861  (set! speed (/ speed 2))
862  'default)
863
864(define (show-cb self)
865  (if (attribute gauge-name show-text:)
866    (begin
867      (attribute-set! gauge-name show-text: 'No)
868      (attribute-set! gauge-name dashed: 'Yes))
869    (begin
870      (attribute-set! gauge-name show-text: 'Yes)
871      (attribute-set! gauge-name dashed: 'No))))
872
873;; load resources
874(load/led "gauge.led")
875
876(define dlg (handle-ref "dlg"))
877(define gauge-name (handle-ref "gauge-name"))
878
879;; set callbacks
880(callback-set! (handle-ref "pause-btn") action: pause-cb)
881(callback-set! (handle-ref "start-btn") action: start-cb)
882(callback-set! (handle-ref "accelerate-btn") action: accelerate-cb)
883(callback-set! (handle-ref "decelerate-btn") action: decelerate-cb)
884(callback-set! (handle-ref "show-btn") action: show-cb)
885(callback-set! (handle-ref "ok-btn") action: ok-cb)
886
887(define tim (timer #:time 100 #:action-cb idle-cb))
888(attribute-set! tim run: 'Yes) ; doesn't work in constructor
889
890(show dlg)
891(main-loop)
892(destroy! dlg)
893(exit 0)
894
895</enscript>
896
897=== Concluding remark
898
899All these examples show, that Iup is really easy to use ...
900
901== Author
902
903[[/users/juergen-lorenz|Juergen Lorenz]]
904
905== Initial version
906
907Nov 25, 2011
908
909== Last updated
910
911Dec 04, 2011
Note: See TracBrowser for help on using the repository browser.