diff options
-rw-r--r-- | Demo/sgi/audio/README | 8 | ||||
-rwxr-xr-x | Demo/sgi/audio/play.py | 75 | ||||
-rw-r--r-- | Demo/sgi/audio_stdwin/README | 19 | ||||
-rwxr-xr-x | Demo/sgi/audio_stdwin/jukebox.py | 321 | ||||
-rwxr-xr-x | Demo/sgi/audio_stdwin/rec.py | 268 | ||||
-rwxr-xr-x | Demo/sgi/audio_stdwin/vumeter.py | 35 | ||||
-rwxr-xr-x | Demo/sgi/flp/test_cb.fd | 75 | ||||
-rwxr-xr-x | Demo/sgi/flp/test_cb.py | 62 | ||||
-rwxr-xr-x | Demo/sgi/flp/test_nocb.fd | 75 | ||||
-rwxr-xr-x | Demo/sgi/flp/test_nocb.py | 45 |
10 files changed, 983 insertions, 0 deletions
diff --git a/Demo/sgi/audio/README b/Demo/sgi/audio/README new file mode 100644 index 0000000..02a3701 --- /dev/null +++ b/Demo/sgi/audio/README @@ -0,0 +1,8 @@ +Programs that demonstrate the use of the audio device on the SGI 4D/25. +These require the built-in module 'audio'. + +XXX This hardware is already obsolete; see ../al for examples of audio +XXX on the Indigo and 4D/35. + +play Read a sound sample from a file and play it through the + speaker. Options to set volume, sampling rate etc. diff --git a/Demo/sgi/audio/play.py b/Demo/sgi/audio/play.py new file mode 100755 index 0000000..adc7625 --- /dev/null +++ b/Demo/sgi/audio/play.py @@ -0,0 +1,75 @@ +#! /usr/local/python + +import sys +import audio + +import string +import getopt +import auds + +debug = [] + +DEF_RATE = 3 + +def main(): + # + gain = 100 + rate = 0 + starter = audio.write + stopper = 0 + # + optlist, args = getopt.getopt(sys.argv[1:], 'adg:r:') + # + for optname, optarg in optlist: + if 0: + pass + elif optname == '-d': + debug.append(1) + elif optname == '-g': + gain = string.atoi(optarg) + if not (0 < gain < 256): + raise optarg.error, '-g gain out of range' + elif optname == '-r': + rate = string.atoi(optarg) + if not (1 <= rate <= 3): + raise optarg.error, '-r rate out of range' + elif optname == '-a': + starter = audio.start_playing + stopper = audio.wait_playing + # + audio.setoutgain(gain) + audio.setrate(rate) + # + if not args: + play(starter, rate, auds.loadfp(sys.stdin)) + else: + real_stopper = 0 + for file in args: + if real_stopper: + real_stopper() + play(starter, rate, auds.load(file)) + real_stopper = stopper + +def play(starter, rate, data): + magic = data[:4] + if magic == '0008': + mrate = 3 + elif magic == '0016': + mrate = 2 + elif magic == '0032': + mrate = 1 + else: + mrate = 0 + if mrate: + data = data[4:] + else: + mrate = DEF_RATE + if not rate: rate = mrate + audio.setrate(rate) + starter(data) + +try: + main() +finally: + audio.setoutgain(0) + audio.done() diff --git a/Demo/sgi/audio_stdwin/README b/Demo/sgi/audio_stdwin/README new file mode 100644 index 0000000..6d96fe1 --- /dev/null +++ b/Demo/sgi/audio_stdwin/README @@ -0,0 +1,19 @@ +Three programs that provide a user interface based upon STDWIN to the +audio device of the SGI 4D/25. These scripts also demonstrate the power +of a set of window interface classes implemented in Python that simplify +the construction of all sorts of buttons, etc. + +XXX This hardware is already obsolete; see ../al for examples of audio +XXX on the Indigo and 4D/35. + +jukebox Browses a directory full of sound samples and lets you + play selected ones. (Probably not fully functional, it + requires a conversion program.) + +rec A tape recorder that lets you record a sound sample, + play it back, and save it to a file. Various options to + set sampling rate, volume etc. When idle it doubles + as a VU meter. + +vumeter A VU meter that displays a history of the volume of + sound recently sampled from the microphone. diff --git a/Demo/sgi/audio_stdwin/jukebox.py b/Demo/sgi/audio_stdwin/jukebox.py new file mode 100755 index 0000000..b223992 --- /dev/null +++ b/Demo/sgi/audio_stdwin/jukebox.py @@ -0,0 +1,321 @@ +#! /usr/local/python + +# JUKEBOX: browse directories full of sampled sound files. +# +# One or more "list windows" display the files and subdirectories of +# the arguments. Double-clicking on a subdirectory opens a new window +# displaying its contents (and so on recursively). Double clicking +# on a file plays it as a sound file (assuming it is one). +# +# Playing is asynchronous: the application keeps listening to events +# while the sample is playing, so you can change the volume (gain) +# during playing, cancel playing or start a new sample right away. +# +# The control window displays the current output gain and a primitive +# "stop button" to cancel the current play request. +# +# Sound files must currently be in Dik Winter's compressed Mac format. +# Since decompression is costly, decompressed samples are saved in +# /usr/tmp/@j* until the application is left. The files are read +# afresh each time, though. + +import audio +import sunaudio +import commands +import getopt +import path +import posix +import rand +import stdwin +from stdwinevents import * +import string +import sys + +from WindowParent import WindowParent +from HVSplit import VSplit +from Buttons import PushButton +from Sliders import ComplexSlider + +# Pathnames + +HOME_BIN_SGI = '/ufs/guido/bin/sgi/' # Directory where macsound2sgi lives +DEF_DB = '/ufs/dik/sounds/Mac/HCOM' # Default directory of sounds + + +# Global variables + +class struct: pass # Class to define featureless structures + +G = struct() # Holds writable global variables + + +# Main program + +def main(): + G.synchronous = 0 # If set, use synchronous audio.write() + G.debug = 0 # If set, print debug messages + G.gain = 75 # Output gain + G.rate = 3 # Sampling rate + G.busy = 0 # Set while asynchronous playing is active + G.windows = [] # List of open windows (except control) + G.mode = 'mac' # Macintosh mode + G.tempprefix = '/usr/tmp/@j' + `rand.rand()` + '-' + # + optlist, args = getopt.getopt(sys.argv[1:], 'dg:r:sSa') + for optname, optarg in optlist: + if optname == '-d': + G.debug = 1 + elif optname == '-g': + G.gain = string.atoi(optarg) + if not (0 < G.gain < 256): + raise optarg.error, '-g gain out of range' + elif optname == '-r': + G.rate = string.atoi(optarg) + if not (1 <= G.rate <= 3): + raise optarg.error, '-r rate out of range' + elif optname == '-s': + G.synchronous = 1 + elif optname == '-S': + G.mode = 'sgi' + elif optname == '-a': + G.mode = 'sun' + # + if not args: + args = [DEF_DB] + # + G.cw = opencontrolwindow() + for dirname in args: + G.windows.append(openlistwindow(dirname)) + # + # + savegain = audio.getoutgain() + try: + # Initialize stdaudio + audio.setoutgain(0) + audio.start_playing('') + dummy = audio.wait_playing() + audio.setoutgain(0) + maineventloop() + finally: + audio.setoutgain(savegain) + audio.done() + clearcache() + +def maineventloop(): + mouse_events = WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP + while G.windows: + type, w, detail = event = stdwin.getevent() + if w == G.cw.win: + if type == WE_CLOSE: + return + G.cw.dispatch(event) + else: + if type == WE_DRAW: + w.drawproc(w, detail) + elif type in mouse_events: + w.mouse(w, type, detail) + elif type == WE_CLOSE: + w.close(w) + del w, event + else: + if G.debug: print type, w, detail + +# Control window -- to set gain and cancel play operations in progress + +def opencontrolwindow(): + cw = WindowParent().create('Jukebox', (0, 0)) + v = VSplit().create(cw) + # + gain = ComplexSlider().define(v) + gain.setminvalmax(0, G.gain, 255) + gain.settexts(' ', ' ') + gain.sethook(gain_setval_hook) + # + stop = PushButton().definetext(v, 'Stop') + stop.hook = stop_hook + # + cw.realize() + return cw + +def gain_setval_hook(self): + G.gain = self.val + if G.busy: audio.setoutgain(G.gain) + +def stop_hook(self): + if G.busy: + audio.setoutgain(0) + dummy = audio.stop_playing() + G.busy = 0 + + +# List windows -- to display list of files and subdirectories + +def openlistwindow(dirname): + list = posix.listdir(dirname) + list.sort() + i = 0 + while i < len(list): + if list[i] == '.' or list[i] == '..': + del list[i] + else: + i = i+1 + for i in range(len(list)): + name = list[i] + if path.isdir(path.join(dirname, name)): + list[i] = list[i] + '/' + width = maxwidth(list) + width = width + stdwin.textwidth(' ') # XXX X11 stdwin bug workaround + height = len(list) * stdwin.lineheight() + stdwin.setdefwinsize(width, min(height, 500)) + w = stdwin.open(dirname) + stdwin.setdefwinsize(0, 0) + w.setdocsize(width, height) + w.drawproc = drawlistwindow + w.mouse = mouselistwindow + w.close = closelistwindow + w.dirname = dirname + w.list = list + w.selected = -1 + return w + +def maxwidth(list): + width = 1 + for name in list: + w = stdwin.textwidth(name) + if w > width: width = w + return width + +def drawlistwindow(w, area): + d = w.begindrawing() + d.erase((0, 0), (1000, 10000)) + lh = d.lineheight() + h, v = 0, 0 + for name in w.list: + d.text((h, v), name) + v = v + lh + showselection(w, d) + +def hideselection(w, d): + if w.selected >= 0: + invertselection(w, d) + +def showselection(w, d): + if w.selected >= 0: + invertselection(w, d) + +def invertselection(w, d): + lh = d.lineheight() + h1, v1 = p1 = 0, w.selected*lh + h2, v2 = p2 = 1000, v1 + lh + d.invert(p1, p2) + +def mouselistwindow(w, type, detail): + (h, v), clicks, button = detail[:3] + d = w.begindrawing() + lh = d.lineheight() + if 0 <= v < lh*len(w.list): + i = v / lh + else: + i = -1 + if w.selected <> i: + hideselection(w, d) + w.selected = i + showselection(w, d) + if type == WE_MOUSE_DOWN and clicks >= 2 and i >= 0: + name = path.join(w.dirname, w.list[i]) + if name[-1:] == '/': + if clicks == 2: + G.windows.append(openlistwindow(name[:-1])) + else: + playfile(name) + +def closelistwindow(w): + remove(G.windows, w) + +def remove(list, item): + for i in range(len(list)): + if list[i] == item: + del list[i] + break + + +# Playing tools + +cache = {} + +def clearcache(): + for x in cache.keys(): + try: + sts = posix.system('rm -f ' + cache[x]) + if sts: + print cmd + print 'Exit status', sts + except: + print cmd + print 'Exception?!' + del cache[x] + +def playfile(name): + if G.mode <> 'mac': + tempname = name + elif cache.has_key(name): + tempname = cache[name] + else: + tempname = G.tempprefix + `rand.rand()` + cmd = HOME_BIN_SGI + 'macsound2sgi' + cmd = cmd + ' ' + commands.mkarg(name) + cmd = cmd + ' >' + tempname + if G.debug: print cmd + sts = posix.system(cmd) + if sts: + print cmd + print 'Exit status', sts + stdwin.fleep() + return + cache[name] = tempname + fp = open(tempname, 'r') + try: + hdr = sunaudio.gethdr(fp) + except sunaudio.error, msg: + hdr = () + if hdr: + data_size = hdr[0] + data = fp.read(data_size) + # XXX this doesn't work yet, need to convert from uLAW!!! + del fp + else: + del fp + data = readfile(tempname) + if G.debug: print len(data), 'bytes read from', tempname + if G.busy: + G.busy = 0 + dummy = audio.stop_playing() + # + # Completely reset the audio device + audio.setrate(G.rate) + audio.setduration(0) + audio.setoutgain(G.gain) + # + if G.synchronous: + audio.write(data) + audio.setoutgain(0) + else: + try: + audio.start_playing(data) + G.busy = 1 + except: + stdwin.fleep() + del data + +def readfile(filename): + return readfp(open(filename, 'r')) + +def readfp(fp): + data = '' + while 1: + buf = fp.read(102400) # Reads most samples in one fell swoop + if not buf: + return data + data = data + buf + +main() diff --git a/Demo/sgi/audio_stdwin/rec.py b/Demo/sgi/audio_stdwin/rec.py new file mode 100755 index 0000000..0caba89 --- /dev/null +++ b/Demo/sgi/audio_stdwin/rec.py @@ -0,0 +1,268 @@ +#! /ufs/guido/bin/sgi/python + +import sys +import audio +import stdwin + +import string +import getopt + +from stdwinevents import * +from Buttons import * +from Sliders import * +#from Soundogram import Soundogram +from VUMeter import VUMeter +from WindowParent import WindowParent, MainLoop +from HVSplit import HSplit, VSplit + +class TimeOutToggleButton(ToggleButton): + def define(self, parent): + self = ToggleButton.define(self, parent) + self.parent.need_timer(self) + self.timer_hook = 0 + return self + def timer(self): + if self.timer_hook: + self.timer_hook(self) + +K = 1024 +BUFSIZE = 30*8*K +Rates = [0, 32*K, 16*K, 8*K] +Magics = ['', '0032', '0016', '0008'] + +class Struct: pass +G = Struct() + +def main(): + # + # Turn off scroll bars + # + stdwin.setdefscrollbars(0, 0) + # + # Set default state + # + G.gain = 60 + G.rate = 3 + G.nomuting = 0 + G.savefile = '@rec' + # + # Set default values + # + G.data = '' + G.playing = 0 + G.recording = 0 + G.sogram = 0 + # + # Parse options + # + optlist, args = getopt.getopt(sys.argv[1:], 'mdg:r:') + # + for optname, optarg in optlist: + if 0: # (So all cases start with elif) + pass + elif optname == '-d': + G.debug = 1 + elif optname == '-g': + G.gain = string.atoi(optarg) + if not (0 < G.gain < 256): + raise optarg.error, '-g gain out of range' + elif optname == '-m': + G.nomuting = (not G.nomuting) + elif optname == '-r': + G.rate = string.atoi(optarg) + if not (1 <= G.rate <= 3): + raise optarg.error, '-r rate out of range' + # + if args: + G.savefile = args[0] + # + # Initialize the sound package + # + audio.setoutgain(G.nomuting * G.gain) # Silence the speaker + audio.setrate(G.rate) + # + # Create the WindowParent and VSplit + # + G.window = WindowParent().create('Recorder', (0, 0)) + w = G.vsplit = VSplit().create(G.window) + # + # VU-meter + # + G.vubtn = VUMeter().define(w) + # + # Radiobuttons for rates + # + r1btn = RadioButton().definetext(w, '32 K/sec') + r1btn.on_hook = rate_hook + r1btn.rate = 1 + # + r2btn = RadioButton().definetext(w, '16 K/sec') + r2btn.on_hook = rate_hook + r2btn.rate = 2 + # + r3btn = RadioButton().definetext(w, '8 K/sec') + r3btn.on_hook = rate_hook + r3btn.rate = 3 + # + radios = [r1btn, r2btn, r3btn] + r1btn.group = r2btn.group = r3btn.group = radios + for r in radios: + if r.rate == G.rate: r.select(1) + # + # Other controls + # + G.recbtn = TimeOutToggleButton().definetext(w, 'Record') + G.recbtn.on_hook = record_on_hook + G.recbtn.timer_hook = record_timer_hook + G.recbtn.off_hook = record_off_hook + # + G.mutebtn = CheckButton().definetext(w, 'Mute') + G.mutebtn.select(not G.nomuting) + G.mutebtn.hook = mute_hook + # + G.playbtn = TimeOutToggleButton().definetext(w, 'Playback') + G.playbtn.on_hook = play_on_hook + G.playbtn.timer_hook = play_timer_hook + G.playbtn.off_hook = play_off_hook + # + G.gainbtn = ComplexSlider().define(w) + G.gainbtn.settexts(' Volume: ', ' ') + G.gainbtn.setminvalmax(0, G.gain, 255) + G.gainbtn.sethook(gain_hook) + # + G.sizebtn = Label().definetext(w, `len(G.data)` + ' bytes') + # + #G.showbtn = PushButton().definetext(w, 'Sound-o-gram...') + #G.showbtn.hook = show_hook + # + G.savebtn = PushButton().definetext(w, 'Save...') + G.savebtn.hook = save_hook + # + G.quitbtn = PushButton().definetext(w, 'Quit') + G.quitbtn.hook = quit_hook + G.playbtn.enable(0) + G.savebtn.enable(0) + #G.showbtn.enable(0) + start_vu() + G.window.realize() + # + # Event loop + # + MainLoop() + +# XXX Disabled... +def show_hook(self): + savetext = self.text + self.settext('Be patient...') + close_sogram() + stdwin.setdefwinsize(400, 300) + win = stdwin.open('Sound-o-gram') + G.sogram = Soundogram().define(win, G.data) + win.buttons = [G.sogram] + self.settext(savetext) + +def close_sogram(): + if G.sogram: + # Break circular references + G.sogram.win.buttons[:] = [] + del G.sogram.win + G.sogram = 0 + +def mute_hook(self): + G.nomuting = (not self.selected) + audio.setoutgain(G.nomuting * G.gain) + +def rate_hook(self): + G.rate = self.rate + audio.setrate(G.rate) + +def record_on_hook(self): + stop_vu() + close_sogram() + audio.setrate(G.rate) + audio.setoutgain(G.nomuting * G.gain) + audio.start_recording(BUFSIZE) + G.recording = 1 + G.playbtn.enable(0) + G.window.settimer(10 * BUFSIZE / Rates[G.rate]) + +def record_timer_hook(self): + if G.recording: + if audio.poll_recording(): + self.hilite(0) + record_off_hook(self) + else: + self.parent.settimer(5) + +def record_off_hook(self): + if not G.recording: + return + G.data = audio.stop_recording() + G.recording = 0 + G.sizebtn.settext(`len(G.data)` + ' bytes') + audio.setoutgain(G.nomuting * G.gain) + G.playbtn.enable((len(G.data) > 0)) + G.savebtn.enable((len(G.data) > 0)) + #G.showbtn.enable((len(G.data) > 0)) + G.window.settimer(0) + start_vu() + +def play_on_hook(self): + stop_vu() + audio.setrate(G.rate) + audio.setoutgain(G.gain) + audio.start_playing(G.data) + G.playing = 1 + G.recbtn.enable(0) + G.window.settimer(max(10 * len(G.data) / Rates[G.rate], 1)) + +def play_timer_hook(self): + if G.playing: + if audio.poll_playing(): + self.hilite(0) + play_off_hook(self) + else: + self.parent.settimer(5) + +def play_off_hook(self): + if not G.playing: + return + x = audio.stop_playing() + G.playing = 0 + audio.setoutgain(G.nomuting * G.gain) + G.recbtn.enable(1) + G.window.settimer(0) + start_vu() + +def gain_hook(self): + G.gain = self.val + if G.playing or G.nomuting: audio.setoutgain(G.gain) + +def save_hook(self): + if not G.data: + stdwin.fleep() + else: + prompt = 'Store sampled data on file: ' + try: + G.savefile = stdwin.askfile(prompt, G.savefile, 1) + except KeyboardInterrupt: + return + try: + fp = open(G.savefile, 'w') + fp.write(Magics[G.rate] + G.data) + except: + stdwin.message('Cannot create ' + file) + +def stop_vu(): + G.vubtn.stop() + +def start_vu(): + G.vubtn.start() + +def quit_hook(self): + G.window.delayed_destroy() + +try: + main() +finally: + audio.setoutgain(0) diff --git a/Demo/sgi/audio_stdwin/vumeter.py b/Demo/sgi/audio_stdwin/vumeter.py new file mode 100755 index 0000000..bfee66e --- /dev/null +++ b/Demo/sgi/audio_stdwin/vumeter.py @@ -0,0 +1,35 @@ +#! /usr/local/python + +import audio +import stdwin + +from VUMeter import VUMeter +from WindowParent import WindowParent +import MainLoop + +NBUFS=20 +BUFSIZE = NBUFS*48 +SCALE=128 + +class MyVUMeter(VUMeter): + def init_reactivity(self): + self.parent.need_mouse(self) + def mouse_down(self, detail): + if self.enabled: + self.stop() + else: + self.start() + def mouse_move(self, detail): pass + def mouse_up(self, detail): pass + +def main(): + audio.setrate(3) + audio.setoutgain(0) + w = WindowParent().create('VU Meter', (200, 100)) + v = MyVUMeter().define(w) + v.start() + w.realize() + while 1: + w.dispatch(stdwin.getevent()) + +main() diff --git a/Demo/sgi/flp/test_cb.fd b/Demo/sgi/flp/test_cb.fd new file mode 100755 index 0000000..e83fd1f --- /dev/null +++ b/Demo/sgi/flp/test_cb.fd @@ -0,0 +1,75 @@ +Magic: 12321 + +Internal Form Definition File + (do not change) + +Number of forms: 1 + +=============== FORM =============== +Name: main_form +Width: 170.000000 +Height: 190.000000 +Number of Objects: 4 + +-------------------- +class: 1 +type: 1 +box: 0.000000 0.000000 170.000000 190.000000 +boxtype: 1 +colors: 47 47 +alignment: 4 +style: 0 +size: 11.000000 +lcol: 0 +label: +name: +callback: +argument: + +-------------------- +class: 11 +type: 0 +box: 10.000000 140.000000 150.000000 40.000000 +boxtype: 1 +colors: 47 47 +alignment: 4 +style: 0 +size: 11.000000 +lcol: 0 +label: Button 1 +name: button1 +callback: button1CB +argument: 0 + +-------------------- +class: 11 +type: 0 +box: 10.000000 100.000000 150.000000 40.000000 +boxtype: 1 +colors: 47 47 +alignment: 4 +style: 0 +size: 11.000000 +lcol: 0 +label: Button 2 +name: button2 +callback: button2CB +argument: 0 + +-------------------- +class: 11 +type: 6 +box: 10.000000 10.000000 150.000000 40.000000 +boxtype: 1 +colors: 47 47 +alignment: 4 +style: 0 +size: 11.000000 +lcol: 0 +label: EXIT +name: exitbutton +callback: exitbuttonCB +argument: 0 + +============================== +create_the_forms diff --git a/Demo/sgi/flp/test_cb.py b/Demo/sgi/flp/test_cb.py new file mode 100755 index 0000000..d622332 --- /dev/null +++ b/Demo/sgi/flp/test_cb.py @@ -0,0 +1,62 @@ +# +# Example 2 - Using fl in python with callbacks. +# +# The form is named 'main_form' and resides on file 'test_cb.fd'. +# It has three objects named button1, button2 and exitbutton. +# All buttons have callbacks with the same names as their corresponding +# buttons but with CB appended. +# +import fl # The forms library +import FL # Symbolic constants for the above +import flp # The module to parse .fd files +import sys + +# The following struct is created to hold the instance variables +# main_form, button1, button2 and exitbutton. + +class myform(): + # + # The init function parses and creates the form, but doesn't + # display it (yet). + def init(self, number): + # + # First we parse the form + parsetree = flp.parse_form('test_cb', 'main_form') + # + # Next we create it + + flp.create_full_form(self, parsetree) + + # And keep our number + self.number = number + return self + + # + # The show function displays the form. It doesn't do any interaction, + # though. + def show(self): + self.main_form.show_form(FL.PLACE_SIZE, 1, '') + + # The callback functions + def button1CB(self, obj, arg): + print 'Button 1 pressed on form', self.number + + def button2CB(self, obj, arg): + print 'Button 2 pressed on form', self.number + + def exitbuttonCB(self, obj, arg): + print 'Ok, bye bye' + sys.exit(0) + +# +# The main program. Instantiate two variables of the forms class +# and interact with them. + +form1 = myform().init(1) +form2 = myform().init(2) + +form1.show() +form2.show() + +obj = fl.do_forms() +print 'do_forms() returned. This should not happen. obj=', obj diff --git a/Demo/sgi/flp/test_nocb.fd b/Demo/sgi/flp/test_nocb.fd new file mode 100755 index 0000000..4d3f7ef --- /dev/null +++ b/Demo/sgi/flp/test_nocb.fd @@ -0,0 +1,75 @@ +Magic: 12321 + +Internal Form Definition File + (do not change) + +Number of forms: 1 + +=============== FORM =============== +Name: main_form +Width: 170.000000 +Height: 190.000000 +Number of Objects: 4 + +-------------------- +class: 1 +type: 1 +box: 0.000000 0.000000 170.000000 190.000000 +boxtype: 1 +colors: 47 47 +alignment: 4 +style: 0 +size: 11.000000 +lcol: 0 +label: +name: +callback: +argument: + +-------------------- +class: 11 +type: 0 +box: 10.000000 140.000000 150.000000 40.000000 +boxtype: 1 +colors: 47 47 +alignment: 4 +style: 0 +size: 11.000000 +lcol: 0 +label: Button 1 +name: button1 +callback: +argument: + +-------------------- +class: 11 +type: 0 +box: 10.000000 100.000000 150.000000 40.000000 +boxtype: 1 +colors: 47 47 +alignment: 4 +style: 0 +size: 11.000000 +lcol: 0 +label: Button 2 +name: button2 +callback: +argument: + +-------------------- +class: 11 +type: 6 +box: 10.000000 10.000000 150.000000 40.000000 +boxtype: 1 +colors: 47 47 +alignment: 4 +style: 0 +size: 11.000000 +lcol: 0 +label: EXIT +name: exitbutton +callback: +argument: + +============================== +create_the_forms diff --git a/Demo/sgi/flp/test_nocb.py b/Demo/sgi/flp/test_nocb.py new file mode 100755 index 0000000..48cee9d --- /dev/null +++ b/Demo/sgi/flp/test_nocb.py @@ -0,0 +1,45 @@ +# +# Example 1 - Using fl in python without callbacks. +# +# The form is named 'main_form' and resides on file 'test_nocb.fd'. +# It has three objects named button1, button2 and exitbutton. +# +import fl # The forms library +import FL # Symbolic constants for the above +import flp # The module to parse .fd files +import sys + +# The following struct is created to hold the instance variables +# main_form, button1, button2 and exitbutton. + +class struct(): pass +container = struct() + +# +# We now first parse the forms file + +parsetree = flp.parse_form('test_nocb', 'main_form') + +# +# Next we create it + +flp.create_full_form(container, parsetree) + +# +# And display it + +container.main_form.show_form(FL.PLACE_MOUSE, 1, '') + +# +# And interact until the exit button is pressed +while 1: + selected_obj = fl.do_forms() + if selected_obj == container.button1: + print 'Button 1 selected' + elif selected_obj == container.button2: + print 'Button 2 selected' + elif selected_obj == container.exitbutton: + print 'Ok, bye bye' + sys.exit(0) + else: + print 'do_forms() returned unknown object ', selected_obj |