############################################################################ # # File: uix.icn # # Subject: Program to translate user interfaces # # Author: Gregg M. Townsend # # Date: May 31, 1994 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # uix translates a user interface prototype or application # built by xib, the old X-Icon Interface Builder, into a skeletal # application of the form used by vib, the new Visual Interface # Builder. The resulting file is a working application containing # all the vidgets (buttons, sliders, etc.) from the input file but # none of the user Icon code. This must be added manually. Some # of the vidget sizes may be incorrect; load and save the file in # vib to fix this. # # usage: uix [file] # # Input is read from the named file, or from standard input if # none is specified. Output is written to standard output. # ############################################################################ # # Requires: Version 9 # ############################################################################ $define YOFF 78 # offset incorporated in y values by XIB $define FONT "lucidasanstypewriter-bold-12" # VIB Font record ob(t, c, v, x, y, w, h, l, s, n, i, j, k, etc) # type callback var x,y,w,h lbl style number initval min max other # main program procedure main(args) local f, line, data, objs, recs, curr, o, fmt, r, c, v, i # open file, skip to data if *args = 0 then f := &input else f := open(args[1]) | stop(&progname, ": can't open ", args[1]) while line := read(f) | stop(&progname, ": EOF hit before finding data") do if match("# Session Code:", line) then break # read data objs := [] # list of objects curr := [] # fields of current object while line := read(f) do { data := line[3:0] # in the following, special case lets Scrollbar consume Slider if data[-5:0] == "_Obj:" & (*curr ~= 1 | *objs == 0) then put(objs, curr := []) put(curr, data) } close(f) # define interpretations fmt := table() fmt["Sizer"] := "txywh" fmt["Button"] := "tcv.xywhl...sn.." fmt["Check"] := "tcv.xywh.." fmt["Text_Input"] := "tcv.xywh.lin.." fmt["Scrollbar"] := "t.cnv.xywh.jkis...cnv.jkxywh..." fmt["Slider"] := "tcnv.xywh.jkis..." fmt["Line"] := "tcv...xywh....sn" fmt["Rect"] := "tcv.xywhn.." fmt["Message"] := "tcv.xywhl...." fmt["Radio_Button"] := "tcv.xywh...n" fmt["Menu"] := "tcv.xywhl..s.." # convert object lists into records recs := [] # list of records every o := !objs do { r := ob() # create empty record f := \fmt[o[1][1:-5]] | { # find appropriate format write(&progname, ": vidget type ", o[1], " unrecognized") next } f ? while c := move(1) do { # get next char from format v := get(o) | "" # get next value, default "" if c ~== "." then r[c] := v # store in rec field named by format } adjust(r) # clean up special cases r.etc := o # save leftovers in "etc" field put(recs, r) # put record on list } # write UI program prologue() write( "#===<>===\tmodify using vib; do not remove this marker line") write("procedure ui(win, cbk)") write("return vsetup(win, cbk,") every output(!recs) # output spec for each line write(" )") write("end") write("#===<>===\tend of section maintained by vib") end # adjust(r) -- clean up record fields including type-dependent cases procedure adjust(r) /r.v := "" # default varname to "" not &null \r.y -:= YOFF # subtract xib header from y value r.t := r.t[1:-5] # chop "_Obj" off name case r.t of { "Sizer": { # Sizer (overall setup) vidget: r.s := FONT # add font expected by VIB } "Line": { # Line vidget: \r.h -:= YOFF # "height" is really 2nd y coordinate } "Text_Input": { # Text vidget: r.t := "Text" # simplify name r.l ||:= "\\\\=" || r.i # concatenate initial value } "Slider" | "Scrollbar": { # Slider, Scrollbar: r.l := r.j || "," || r.k || "," || r.i # add bounds and init value } "Message": { # Message vidget: r.t := "Label" # change name } "Radio_Button": { # Radio_Button vidget: r.t := "Choice" # simplify name } } return end # prologue() -- write boilerplate prologue to acual spec procedure prologue() every write(![ "# User interface specification translated to vib format by uix", "# (Load and save this file once in vib to correct size information.)", "#", "# This is a working program that responds to vidget events by printing", "# messages. Use a text editor to replace this skeletal program with your", "# own code. Retain the vib section at the end and use vib to make any", "# changes to the interface.", "#", "# When a callback is generated, but there is no callback procedure, a", "# message is printed. Remove the vecho argument below to prevent this.", "", "link vsetup", "", "procedure main()", " local vidgets", "", " vidgets := ui(, vecho)\t\t\t# set up vidgets", " GetEvents(vidgets[\"root\"], QuitCheck)\t# enter event loop", "end", "", "", ""]) end # output(r) -- output one record in vib format procedure output(r) if /r.t then fail writes(" [\"") writes(r.v, ":", r.t, ":", r.s, ":", r.n, ":") writes(r.x, ",", r.y, ",", r.w, ",", r.h, ":") writes(r.l, "\",", r.c) if r.t == "Menu" then outmenu(r.etc) else if *r.etc > 0 then { writes(",\n [", image(get(r.etc))) while writes(",", image(get(r.etc))) writes("]") } write("],") return end # outmenu(lst) -- output a list of menu entries procedure outmenu(lst) local msize msize := get(lst) if msize = 0 then return writes(",\n [") outentry(lst) every 2 to msize do { writes(",") outentry(lst) } writes("]") return end # outentry(lst) -- output menu entry procedure outentry(lst) writes(image(get(lst))) # output label get(lst) # skip unused data get(lst) outmenu(lst) # output submenu (if any) return end