diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2013-01-27 23:51:56 +0000 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2013-01-27 23:51:56 +0000 |
commit | 6ab0c0f5bf14ed9c15370407b9ee7e0b4b089ae1 (patch) | |
tree | 926065cf45450116098db664e3c61dced9e1f21a /ipl/gpacks/vib | |
download | icon-6ab0c0f5bf14ed9c15370407b9ee7e0b4b089ae1.tar.gz |
Initial upstream version 9.4.3upstream/9.4.3
Diffstat (limited to 'ipl/gpacks/vib')
-rw-r--r-- | ipl/gpacks/vib/Makefile | 35 | ||||
-rw-r--r-- | ipl/gpacks/vib/busy.icn | 144 | ||||
-rw-r--r-- | ipl/gpacks/vib/dlog.icn | 40 | ||||
-rw-r--r-- | ipl/gpacks/vib/vib.icn | 318 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibbttn.icn | 220 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibdefn.icn | 75 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibedit.icn | 922 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibfile.icn | 603 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibglbl.icn | 38 | ||||
-rw-r--r-- | ipl/gpacks/vib/viblabel.icn | 125 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibline.icn | 197 | ||||
-rw-r--r-- | ipl/gpacks/vib/viblist.icn | 168 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibmenu.icn | 468 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibradio.icn | 209 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibrect.icn | 135 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibsizer.icn | 197 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibslidr.icn | 207 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibtalk.icn | 193 | ||||
-rw-r--r-- | ipl/gpacks/vib/vibtext.icn | 163 |
19 files changed, 4457 insertions, 0 deletions
diff --git a/ipl/gpacks/vib/Makefile b/ipl/gpacks/vib/Makefile new file mode 100644 index 0000000..69283df --- /dev/null +++ b/ipl/gpacks/vib/Makefile @@ -0,0 +1,35 @@ +# Makefile for vib, the Visual Interface Builder + +ICONT = icont +IFLAGS = -us +ITRAN = $(ICONT) $(IFLAGS) + +OBJ = vib.u2 vibbttn.u2 vibedit.u2 vibfile.u2 vibglbl.u2 \ + viblabel.u2 vibline.u2 viblist.u2 vibmenu.u2 vibradio.u2 \ + vibrect.u2 vibsizer.u2 vibslidr.u2 vibtalk.u2 vibtext.u2 + +.SUFFIXES: .icn .u2 .gif .ps + +.icn.u2: ; $(ITRAN) -c $< +.icn: ; $(ITRAN) $< + +.gif.ps: + giftoppm $< | ppmtopgm | pnmtops -scale .75 >$@ + +vib: $(OBJ) + $(ITRAN) -o vib $(OBJ) + +$(OBJ): vibdefn.icn + + +ipd doc: ipd265.ps + +ipd265.ps: ipd265.bibl fig1.ps fig2.ps + bib -t stdn -p /r/che/usr/ralph/docs/reg.index <ipd265.bibl | \ + psfig | psroff -t >ipd265.ps + +Iexe: vib + cp vib ../../iexe/ + +clean Clean: + rm -f vib *.ps *.u[12] app vibpro* core busy dlog diff --git a/ipl/gpacks/vib/busy.icn b/ipl/gpacks/vib/busy.icn new file mode 100644 index 0000000..da3095f --- /dev/null +++ b/ipl/gpacks/vib/busy.icn @@ -0,0 +1,144 @@ +# busy.icn -- vib application demo and tester +# +# A complex user interface that does nothing useful +# (except to assist in testing VIB) + +link vsetup + +global vidgets + + +# main procedure + +procedure main(args) + + vidgets := ui(args, cbk) # set up vidgets + + VSetItems(vidgets["list1"], + ["Select", " your", "custom", "pizza", "below"]) + VSetItems(vidgets["list2"], + ["individual", "small", "medium", "large", "family"]) + VSetItems(vidgets["list3"], + ["anchovies", "bacon", "black olive", "bell pepper", "broccoli", + "capicolla", "garlic", "green olive", "linguisa", "mushroom", "onion", + "pepperoni", "pineapple", "sausage", "spinach", "tomato", "extra cheese"]) + + GetEvents(vidgets["root"], quitcheck) # enter event loop +end + + +# quitcheck() -- handle events that fall outside the vidgets + +procedure quitcheck(e) + if e === QuitEvents() then + exit() + else + write("unhandled event: ", image(e)) +end + + +#===<<vib:begin>>=== modify using vib; do not remove this marker line +procedure ui_atts() + return ["size=490,401", "bg=pale gray", "label=An Icon Busy-Box"] +end + +procedure ui(win, cbk) +return vsetup(win, cbk, + [":Sizer:::0,0,490,401:An Icon Busy-Box",], + ["DUMP:Button:regular::11,31,73,20:DUMP",dump], + ["QUIT:Button:regular::11,56,73,20:QUIT",quit], + ["Toggles:Label:::25,159,49,13:Toggles",], + ["b1:Button:regular::129,189,28,27:1",], + ["b2:Button:regular::129,216,28,27:2",], + ["b3:Button:regular::129,243,28,27:3",], + ["b4:Button:regular::129,270,28,27:4",], + ["b5:Button:regular::129,297,28,27:5",], + ["check1:Button:xbox:1:21,282,37,37:",], + ["checko:Button:check:1:123,108,69,20:checko",], + ["circlo:Button:circle:1:123,83,69,20:circlo",], + ["line1:Line:::128,154,186,171:",], + ["line2:Line:::131,147,189,164:",], + ["line3:Line:::12,24,150,24:",], + ["list1:List:r::350,10,120,115:",], + ["list2:List:w::350,141,120,115:",], + ["list3:List:a::350,274,120,115:",], + ["menu1:Menu:pull::12,110,71,21:Food Menu",foodhandler, + ["American", + ["Burgers","Barbecue","Tex-Mex","Creole","New England"], + "Chinese", + ["Cantonese","Mandarin","Szechuan"], + "Greek","Italian", + ["Pasta","Pizza","Sandwiches", + ["Grinder","Hoagie","Poor Boy","Submarine"]], + "Mexican", + ["Sonoran","Chihuahuan","Angelino","Taco Bell"], + "Japanese","Korean","French","German","English", + "Scottish","Irish"]], + ["sbar1:Scrollbar:v:1:316,10,18,379:77,22,66",], + ["sbar2:Scrollbar:h::20,345,280,18:999,1,777",], + ["slider1:Slider:h::20,369,280,18:0,1000,200",], + ["slider2:Slider:v:1:290,10,18,312:33,67,44",], + ["stations:Choice::5:204,83,57,105:",, + ["KUAT","KUAZ","KXCI","KJZZ","WOI"]], + ["tcheck:Button:checkno:1:23,235,62,20:check",], + ["tcircle:Button:circleno:1:22,256,69,20:circle",], + ["text:Text::12:122,54,157,19:password:\\=swordfish",], + ["title1:Label:::11,10,126,13:Some VIB Experimen",], + ["title2:Label:::137,10,14,13:ts",], + ["tline:Line:::26,181,92,181:",], + ["tregular:Button:regular:1:23,189,56,20:regular",], + ["tsimple:Button:regularno:1:24,213,77,20:no-outline",], + ["xgrooved:Button:xboxno:1:64,284,33,33:",], + ["rectx:Rect:grooved::62,282,37,37:",], + ["rect1:Rect:grooved::188,202,30,50:",], + ["rect2:Rect:sunken::229,201,30,50:",], + ["rect3:Rect:raised::188,263,30,50:",], + ["rect4:Rect:invisible::230,263,30,50:",], + ["trect:Rect:grooved::12,151,98,176:",], + ) +end +#===<<vib:end>>=== end of section maintained by vib + + +procedure cbk(v, x) + writes("CALLBACK: ") + VEcho(v, x) + return +end + +procedure foodhandler(v, x) + writes("FOOD: ") + every writes(" ", !x) + write() + return +end + +procedure dump(v, x) + local l, id + + write() + write("key v.id VGetState(v) image(v)") + write("--------- --------- ------------ -----------------------------") + l := sort(vidgets, 3) + while id := get(l) do { + v := get(l) + write(left(\id | "**NULL**", 12), left(\v.id | "**NULL**", 12), + left(vimage(VGetState(v)) | "---", 15), image(v)) + } + write() + return +end + +procedure vimage(a) + local s + + if (type(a) ~== "list") then + return image(a) + s := "[" + every s ||:= image(!a) || "," + return s[1:-1] || "]" +end + +procedure quit(v, x) + exit() +end diff --git a/ipl/gpacks/vib/dlog.icn b/ipl/gpacks/vib/dlog.icn new file mode 100644 index 0000000..13dc394 --- /dev/null +++ b/ipl/gpacks/vib/dlog.icn @@ -0,0 +1,40 @@ +# dlog.icn -- VIB dialog box demo and test program + +procedure main(args) + Window("font=sans,bold,24", args) + WAttrib("fillstyle=textured", "pattern=grains") + FillRectangle() + WAttrib("fillstyle=solid") + CenterString(247, 102, "Dialog Box Test") + Fg("white") + CenterString(250, 100, "Dialog Box Test") + while dl() ~== "quit" +end + +link dsetup + +#===<<vib:begin>>=== modify using vib; do not remove this marker line +procedure dl(win, deftbl) +static dstate +initial dstate := dsetup(win, + [":Sizer::1:0,0,270,300:",], + ["checkbox:Button:check:1:29,52,83,20:checkbox",], + ["line:Line:::15,233,255,233:",], + ["ne:Button:regular:1:235,0,35,20:ne",], + ["nw:Button:regular:1:0,0,35,20:nw",], + ["quit:Button:regular::137,257,49,20:quit",], + ["radio:Choice::4:180,49,57,84:",, + ["KUAT","KUAZ","KMCI","KJZZ"]], + ["repeat:Button:regular:-1:70,256,49,20:repeat",], + ["scroller:Scrollbar:h:1:35,183,200,18:0.0,1.0,0.5",], + ["se:Button:regular:1:235,280,35,20:se",], + ["slider:Slider:h:1:35,154,200,18:0.0,1.0,0.5",], + ["sw:Button:regular:1:0,280,35,20:sw",], + ["text:Text::11:34,112,122,19:Text:\\=",], + ["title:Label:::73,17,105,13:Dialog Box Test",], + ["xbox:Button:xbox:1:30,80,25,25:",], + ["xlabel:Label:::65,85,28,13:xbox",], + ) +return dpopup(win, deftbl, dstate) +end +#===<<vib:end>>=== end of section maintained by vib diff --git a/ipl/gpacks/vib/vib.icn b/ipl/gpacks/vib/vib.icn new file mode 100644 index 0000000..1423036 --- /dev/null +++ b/ipl/gpacks/vib/vib.icn @@ -0,0 +1,318 @@ +############################################################################ +# +# File: vib.icn +# +# Subject: Program to build Icon interfaces +# +# Authors: Mary Cameron and Gregg M. Townsend +# +# Date: May 25, 2001 +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ +# +# For documentation, see IPD284: +# http://www.cs.arizona.edu/icon/docs/ipd284.htm +# +############################################################################ + +# Version 1 (XIB): Original version +# Version 2 (VIB): Compact specifications in same file as source +# Version 3 (VIB, Dec 94): 3-D appearance, uses VIB for own dialogs +# Oct 96: add list vidget + +$include "keysyms.icn" +$include "vdefns.icn" +$include "vibdefn.icn" + +link drag +link dsetup +link graphics +link vsetup +link interact + +link vibbttn +link vibedit +link vibfile +link vibglbl +link viblabel +link vibline +link viblist +link vibmenu +link vibradio +link vibrect +link vibsizer +link vibslidr +link vibtalk +link vibtext + +global CHOSEN # object picked from Select menu + +############################################################################ +# main() opens a window, creates the palette and menus, initializes +# global variables, and starts up the WIT event loop. +############################################################################ +procedure main(args) + local edit_menu, file_menu, x, y + + Window("size=640,480", "label= ", args) + + &error := 1 + WAttrib("resize=on") + &error := 0 + + VSetFont() + APPWIN := Clone() | stop("can't clone window") + XORWIN := Clone("drawop=reverse") | stop("can't clone window") + + SESSION := def_extn("" ~== args[1]) | newname() + label_session() + + PAD := WAttrib("fheight") + 6 + LBMASK := &ascii[32+:95] -- '\"\\' + IDMASK := &ascii[32+:95] -- '\"\\:' + CBMASK := &letters ++ &digits ++ '_' + + O_LIST := [] + P_LIST := [] + SIZER := create_sizer() + + ROOT := Vroot_frame(&window) + edit_menu := Vsub_menu(&window, + "copy @C", menu_cb, + "delete @X", menu_cb, + "undelete @U", menu_cb, + "align vert @V", menu_cb, + "align horz @H", menu_cb) + file_menu := Vsub_menu(&window, + "new @N", menu_cb, + "open @O", menu_cb, + "save @S", menu_cb, + "save as ", menu_cb, + "refresh @R", menu_cb, + "prototype @P", menu_cb, + "quit @Q", menu_cb) + MENUBAR := Vmenu_bar(&window, "File ", file_menu, "Edit ", edit_menu) + VInsert(ROOT, MENUBAR, 0, 0) + SELECT := Vpane(&window, select_cb, , , TextWidth("Select") + 8, MENUBAR.ah) + VInsert(ROOT, SELECT, MENUBAR.aw, 0) + + dialogue() + + VResize(ROOT) + CANVASY := MENUBAR.ah + 3 + PAL_H + 4 + Clip(APPWIN, 0, CANVASY, 9999, 9999) + + DRAGWIN := Clone(APPWIN, "bg=blackish gray") | stop("can't clone APPWIN") + + create_palette() + + if not (args[1] & load_session(SESSION)) then { + draw_header() + draw_canvas() + } + + GetEvents(ROOT, vib_event_loop) +end + +############################################################################ +# menu_cb() is the callback routine for the file and edit menus. +############################################################################ +procedure menu_cb(wit, value) + local cmd + + cmd := trim(value[1] ? tab(upto('@') | 0)) + case cmd of { + + # file menu + "n" | "new" : new_session() + "o" | "open" : if flush_session() then open_session() + "s" | "save" : save_session(SESSION) + "save as" : vib_save_as("file to save: ", "") + "r" | "refresh" : redraw_screen() + "p" | "prototype" : prototype() + "q" | "quit" : if flush_session() then exit() + + # edit menu + "c" | "d" | "copy" : copy_focus() + "x" | "\d" | "delete" : delete_focus() + "u" | "undelete" : undelete() + "v" | "align vert" : if \FOCUS then set_align("alignv") + "h" | "align horz" : if \FOCUS then set_align("alignh") + } +end + +############################################################################ +# select_cb() is the callback routine for the Select pseudo-menu. +############################################################################ +procedure select_cb(wit, ev) + local i, idlist, mlist, smenu, obj + + if not (ev === (&lpress | &ldrag | &mpress | &mdrag | &rpress | &rdrag)) then + return + + idlist := set() + every insert(idlist, (!O_LIST).id) + idlist := sort(idlist) + + mlist := [&window] + every put(mlist, !idlist, choice_cb) + smenu := Vmenu_bar_item(&window, "Select", , , , , Vsub_menu ! mlist) + VInsert(ROOT, smenu, wit.ax, wit.ay) + VResize(smenu) + + CHOSEN := &null + VEvent(smenu, &lpress) + VRemove(ROOT, smenu, 1) + + if \CHOSEN then + every obj := !O_LIST do + if obj.id == CHOSEN then { + focus_object(obj) + break + } + return +end + +############################################################################ +# choice_cb() is the callback routine for a chosen Select entry. +############################################################################ +procedure choice_cb(wit, value) + CHOSEN := value[1] +end + +############################################################################ +# vib_event_loop() is called by the WIT library whenever an event +# occurs that does not correspond to WIT objects. +############################################################################ +procedure vib_event_loop(e, x, y) + local f, obj, flag, diffx, diffy + + case e of { + &meta & "I": snapshot() + &meta & !"nosrpqcdxuvh": menu_cb(, e) + "\d": menu_cb(, e) + Key_Left | Key_KP_Left: shift_focus(-1, 0) + Key_Right | Key_KP_Right: shift_focus(+1, 0) + Key_Up | Key_KP_Up: shift_focus(0, -1) + Key_Down | Key_KP_Down: shift_focus(0, +1) + &resize: { + if SIZER.x+10 > &x then + SIZER.x := &x - 11 + if SIZER.y+10 > &y then + SIZER.y := maximum(&y - 11, CANVASY) + redraw_screen() + DIRTY := 1 + } + &mpress: { + obj := object_of_event(x, y) + if type(obj) == "menu_obj" then { + focus_object(obj) + simulate_menu(obj) + } + } + &rpress: { + if on_target(SIZER, x, y) then + display_sizer_atts(SIZER) + else { + obj := object_of_event(x, y) + focus_object(\obj) + display_talk(\FOCUS) + } + } + &lpress: { + if \ALIGN then { + obj := object_of_event(x, y) + if \obj & \FOCUS then { + unfocus_object(f := FOCUS) + if ALIGN == "alignv" then + move_object(obj, obj.x, f.y) + else + move_object(obj, f.x, obj.y) + focus_object(f) + } + else + unset_align() + } + else { # not in ALIGN mode + if \(obj := palette_object_of_event(x, y)) then { + obj := create_object_instance(obj) + focus_object(obj) + &y := CANVASY + 4 + drag_obj(APPWIN, obj) + } + else if on_target(SIZER, x, y) then + drag_sizer() + else if flag := on_focus(\FOCUS, x, y) then + resize_drag(FOCUS, flag) + else if \(obj := object_of_event(x, y)) then + drag_obj(DRAGWIN, obj) + else + unfocus_object(\FOCUS) + } + } + } +end + +############################################################################ +# drag_obj() moves an object to follow the mouse pointer. +############################################################################ +procedure drag_obj(win, obj) + unfocus_object(\FOCUS) + case type(obj) of { + "rect_obj": { + # use APPWIN, not DRAGWIN, to get XOR color correct + DragOutline(APPWIN, obj.x, obj.y, obj.w, obj.h) + } + "line_obj": + drag_line(obj) + default: { + EraseArea(APPWIN, obj.x, obj.y, obj.w, obj.h) + draw_object(obj) + Drag(win, obj.x, obj.y, obj.w, obj.h) + } + } + + if obj.x ~= &x | obj.y ~= &y then + move_object(obj, &x, &y) + focus_object(obj) +end + +############################################################################ +# resize_drag() resizes an object using the mouse pointer. +############################################################################ +procedure resize_drag(obj, flag) + local e, orig, winw, winh + + orig := copy(obj) + unfocus_object(obj) + draw_outline(obj) + winw := WAttrib("width") + winh := WAttrib("height") + repeat { + e := Event() + &x <:= 0 + &x >:= winw - 1 + &y <:= CANVASY + &y >:= winh - 1 + case e of { + &ldrag: { + resize_object(obj, &x, &y, flag) + DIRTY := 1 + } + &lrelease: { + draw_outline(obj) + erase_object(orig) + draw_overlap(orig) + if type(obj) ~== "line_obj" then + VResize(obj.v, obj.x, obj.y, obj.w, obj.h) + draw_object(obj) + focus_object(obj) + return + } + } + } +end diff --git a/ipl/gpacks/vib/vibbttn.icn b/ipl/gpacks/vib/vibbttn.icn new file mode 100644 index 0000000..362b807 --- /dev/null +++ b/ipl/gpacks/vib/vibbttn.icn @@ -0,0 +1,220 @@ +############################################################################ +# +# vibbttn.icn -- procedures for defining a button object +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$include "vibdefn.icn" + +########################################################################## +# button_obj: +# v : vidget used for drawing text input object +# proc : name of user callback procedure +# id : unique means of identifying instance +# x,y,w,h : bounding box +# label : button label +# style : button style +# toggle : is this a toggle button? +# dflt : is this button the default in a dialog box? +# focus : should focus lines be drawn around this object? +########################################################################## +record button_obj(v, proc, id, x, y, w, h, + label, style, toggle, dflt, focus) + + +########################################################################## +# create_button() creates a button instance and draws the button if +# it is a first class object. +########################################################################## +procedure create_button(x, y, w, h, label, style, toggle, dflt) + local r, id + + id := next_id("button") + /style := DEFAULT_BUTTON_STYLE + r := button_obj(, "button_cb" || id, "button" || id, + x, y, w, h, label, style, toggle, dflt, 0) + r.v := Vbutton(ROOT, x, y, APPWIN, label, , id, style, w, h) + VRemove(ROOT, r.v, 1) + return r +end + +########################################################################## +# draw_button() draws the given button in that button's style. +########################################################################## +procedure draw_button(r) + VResize(r.v, r.x, r.y, r.w, r.h) + VDraw(r.v) + if \r.dflt then + BevelRectangle(APPWIN, r.x - 4, r.y - 4, r.w + 8, r.h + 8, -2) + return r +end + +########################################################################## +# update_button_bb() updates various attributes of the button that +# change when the button is resized, etc. +########################################################################## +procedure update_button_bb(r) + local tempy, temph, vpad, hpad, sp, sz + + vpad := 4 # vertical padding + hpad := 7 # horizontal padding + sp := 11 # space between circle/box and text + r.w <:= MIN_W + r.h <:= MIN_H + case r.style of { + "check" | "circle" | "checkno" | "circleno": { + sz := integer(WAttrib(APPWIN, "fheight") * 0.75) + r.w <:= sz + sp + TextWidth(APPWIN, r.label) + hpad + r.h <:= WAttrib(APPWIN, "fheight") + vpad + } + "regular" | "regularno": { + r.w <:= TextWidth(APPWIN, r.label) + hpad + r.h <:= WAttrib(APPWIN, "fheight") + vpad + } + "xbox" | "xboxno": { + r.w <:= r.h + r.h <:= r.w + r.label := &null + } + } +end + +########################################################################## +# load_button() restores a button object from session code. +########################################################################## +procedure load_button(r, o) + r.label := o.lbl + r.style := o.sty + case o.num of { + "1": r.toggle := 1 + "-1": r.dflt := 1 + } + r.v := Vbutton(ROOT, r.x, r.y, APPWIN, r.label, , r.id, r.style, r.w, r.h) + VRemove(ROOT, r.v, 1) +end + +########################################################################## +# load_xbox() makes an xbox button object from an old checkbox entry. +########################################################################## +procedure load_xbox(r, o) + r.label := "" + r.style := "xbox" + r.toggle := 1 +end + +########################################################################## +# save_button() augments the record for saving a button object. +########################################################################## +procedure save_button(r, o) + r.typ := "Button" + r.lbl := o.label + r.sty := o.style + if \o.dflt then + r.num := -1 + else + r.num := o.toggle + return +end + +########################################################################## +# display_button_atts() displays the attribute sheet with the current +# attributes for the given button instance. +########################################################################## +procedure display_button_atts(object) + local s, o, t, d + + d := object.dflt + + s := object.style + o := 1 + if s[-2:0] == "no" then { + s := s[1:-2] + o := &null + } + + t := table() + t["_style"] := s + t["_outline"] := o + t["_toggle"] := object.toggle + t["_dflt"] := object.dflt + t["a_label"] := object.label + t["b_id"] := object.id + t["c_callback"] := object.proc + t["d_x"] := object.x + t["e_y"] := object.y - CANVASY + t["f_width"] := object.w + t["g_height"] := object.h + + repeat { + if button_dialog(t) == "Cancel" then + fail + + if illegal(t["a_label"], "Label", "l") | + illegal(t["b_id"], "ID", "s") | + illegal(t["c_callback"], "Callback", "p") | + illegal(t["d_x"], "X", "i") | + illegal(t["e_y"], "Y", "i") | + illegal(t["f_width"], "Width", MIN_W) | + illegal(t["g_height"], "Height", MIN_H) + then + next + + if t["_style"] ? ="xbox" & *t["a_label"] > 0 then { + Notice("No text is allowed with xbox style") + next + } + if \t["_toggle"] & \t["_dflt"] then { + Notice("A toggle button cannot be a dialog default") + next + } + + object.style := t["_style"] + if /t["_outline"] then + object.style ||:= "no" + + object.dflt := t["_dflt"] + object.toggle := t["_toggle"] + object.label := t["a_label"] + object.id := t["b_id"] + object.proc := t["c_callback"] + + object.v.style := object.style + object.v.s := object.label + + unfocus_object(object) + if /object.dflt & \d then # remove default frame + EraseArea(object.x - 4, object.y - 4, object.w + 8, object.h + 8) + move_object(object, + t["d_x"], t["e_y"] + CANVASY, t["f_width"], t["g_height"]) + focus_object(object) + break + } +end + +#===<<vib:begin>>=== modify using vib; do not remove this marker line +procedure button_dialog(win, deftbl) +static dstate +initial dstate := dsetup(win, + ["button_dialog:Sizer::1:0,0,392,240:",], + ["_cancel:Button:regular::211,189,50,30:Cancel",], + ["_dflt:Button:check:1:245,148,125,20:dialog default",], + ["_okay:Button:regular:-1:141,189,50,30:Okay",], + ["_outline:Button:check:1:245,85,76,20:outline",], + ["_style:Choice::4:142,85,78,84:",, + ["regular","check","circle","xbox"]], + ["_toggle:Button:check:1:245,116,76,20:toggle",], + ["a_label:Text::40:13,14,360,19:label: \\=",], + ["b_id:Text::40:13,35,360,19:ID: \\=",], + ["c_callback:Text::40:13,56,360,19:callback: \\=",], + ["d_x:Text::3:13,85,101,19: x: \\=",], + ["e_y:Text::3:13,106,101,19: y: \\=",], + ["f_width:Text::3:13,131,101,19: width: \\=",], + ["g_height:Text::3:13,152,101,19: height: \\=",], + ) +return dpopup(win, deftbl, dstate) +end +#===<<vib:end>>=== end of section maintained by vib diff --git a/ipl/gpacks/vib/vibdefn.icn b/ipl/gpacks/vib/vibdefn.icn new file mode 100644 index 0000000..02d8a04 --- /dev/null +++ b/ipl/gpacks/vib/vibdefn.icn @@ -0,0 +1,75 @@ +############################################################################ +# +# vibdefn.icn -- manifest constants +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$define PAL_H 36 # height of palette entry +$define PAL_W 48 # width of palette entry + +$define SZDIM 9 # sizer dimensions + +$define DEFAULT_BUTTON_STYLE "regular" # default button style +$define MIN_W 10 # minimum object width +$define MIN_H 10 # minimum object height + +$define TEXTCHARS 40 # size of hand-built text field +$define TEXTWIDTH (20 + 7 * TEXTCHARS) # space used for same +$define LONGTEXT 50 # size of long text fields + + +# alternate keypad symbols not always set + +$ifndef Key_KP_Left + $define Key_KP_Left Key_Left +$endif +$ifndef Key_KP_Right + $define Key_KP_Right Key_Right +$endif +$ifndef Key_KP_Up + $define Key_KP_Up Key_Up +$endif +$ifndef Key_KP_Down + $define Key_KP_Down Key_Down +$endif + + +# file names and commands for prototyping + +$ifdef _UNIX + $define EXECPROTO ("./" || PROTOEXE || " && rm -f " || PROTOEXE || " &") +$endif + +$ifdef _CYGWIN + $define EXECPROTO ("./" || PROTOEXE || " && rm -f " || PROTOEXE || " &") +$endif + +$ifdef _MS_WINDOWS + $define PROTOEXE "vibproto.exe" +$endif + +# defaults used if not set above + +$ifndef PROTOFILE # prototype file name + $define PROTOFILE "vibproto.icn" +$endif + +$ifndef PROTOEXE # executable file name + $define PROTOEXE "vibproto" +$endif + +$ifndef BUILDPROTO # build command + $ifdef _JAVA + $define BUILDPROTO ("jcont -s -o" || PROTOEXE || " " || PROTOFILE) + $else # _JAVA + $define BUILDPROTO ("icont -s -o" || PROTOEXE || " " || PROTOFILE) + $endif # _JAVA +$endif + +$ifndef EXECPROTO # execute command + $define EXECPROTO PROTOEXE +$endif diff --git a/ipl/gpacks/vib/vibedit.icn b/ipl/gpacks/vib/vibedit.icn new file mode 100644 index 0000000..b8f07e1 --- /dev/null +++ b/ipl/gpacks/vib/vibedit.icn @@ -0,0 +1,922 @@ +############################################################################ +# +# vibedit.icn -- shared graphical editing routines +# +## ######################################################################### +# +# This file is in the public domain. +# +############################################################################ + +$include "vibdefn.icn" +$include "vdefns.icn" + +record palette_obj(name, x, y, bwimage, colrimage) + +############################################################################ +# next_id() generates an ID number for a new object +############################################################################ +procedure next_id(s) + local obj, n + + n := 0 + every obj := !O_LIST do + obj.id ? + if =s then + n <:= integer(tab(0)) # find highest used so far + return n + 1 +end + +############################################################################ +# strip() deletes trailing blanks from the incoming string. +############################################################################ +procedure strip(s) + local index + + index := 0 + every index := *s to 1 by -1 do + if s[index] ~== " " then break + return s[1:index+1] +end + +############################################################################ +# set_align() sets the align flag and changes the cursor to indicate that +# the system is in align mode. +############################################################################ +procedure set_align(kind) + ALIGN := kind + if kind == "alignv" then + WAttrib("pointer=" || ("top side" | "sb v double arrow" | "crosshair")) + else + WAttrib("pointer=" || ("left side" | "sb h double arrow" | "crosshair")) +end + +############################################################################ +# unset_align() unsets the align flag and restores the cursor to its +# original state. +############################################################################ +procedure unset_align() + ALIGN := &null + WAttrib("pointer=" || ("left ptr" | "arrow")) +end + +############################################################################ +# minimum() returns the smaller of two numeric values. +############################################################################ +procedure minimum(x, y) + return x > y | x +end + +############################################################################ +# maximum() returns the larger of two numeric values. +############################################################################ +procedure maximum(x, y) + return x < y | x +end + +############################################################################ +# draw_outline() draws an outline for the given object. Used for resizing. +############################################################################ +procedure draw_outline(object) + case type(object) of { + "line_obj" : outline_line(object) + default : DrawRectangle(XORWIN, + object.x-1, object.y-1, object.w+1, object.h+1) + } +end + +############################################################################ +# update_bb() calls update routines for the various object types so +# that attributes correctly get updated when an object is +# resized or a label changes, etc. +############################################################################ +procedure update_bb(object) + case type(object) of { + "button_obj" : update_button_bb(object) + "radio_button_obj": update_radio_bb(object) + "line_obj" : update_line_bb(object) + "slider_obj" : update_slider_bb(object) + "text_input_obj" : update_text_input_bb(object) + "label_obj" : update_label_bb(object) + "menu_obj" : update_menu_bb(object) + "list_obj" : update_list_bb(object) + # nothing to do for rectangles + } +end + +############################################################################ +# move_object() is called to reposition, resize, and redraw an object. +############################################################################ +procedure move_object(object, x, y, w, h) + + erase_object(object) + draw_overlap(object) + + if type(object) == "line_obj" then { + object.x2 := object.x2 - object.x + x + object.y2 := object.y2 - object.y + y + object.x1 := object.x1 - object.x + x + object.y1 := object.y1 - object.y + y + update_bb(object) + } + else { + x <:= 0 + y <:= CANVASY # ensure object does not overlap palette + object.x := x + object.y := y + object.w := \w + object.h := \h + update_bb(object) + VResize(object.v, object.x, object.y, object.w, object.h) + } + + draw_object(object) + DIRTY := 1 +end + +############################################################################ +# resize_object() is called to resize the outline of an object. First, +# draw_outline() is called to erase the outline, then the +# attributes are updated, then draw_outline is called to +# draw the new outline. +############################################################################ +procedure resize_object(object, x, y, direction) + local neww, newh, newy, xcorner, ycorner + + # move particular enpoint of line and adjust bounding box of line + if type(object) == "line_obj" then { + draw_outline(object) + if direction == "lpt" then { + object.x1 := x + object.y1 := maximum(CANVASY, y) + } + else if direction == "rpt" then { + object.x2 := x + object.y2 := maximum(CANVASY, y) + } + update_bb(object) + draw_outline(object) + return + } + + # all other objects can be resized freely, + # subject to minimum width/height imposed in update_bb() + + draw_outline(object) + y <:= CANVASY + ycorner := direction[1] # "u" or "l" + xcorner := direction[2] # "l" or "r" + + if xcorner == "r" then { + neww := x - object.x + neww <:= MIN_W + } + else { + neww := object.w + object.x - x + neww <:= MIN_W + object.x +:= object.w - neww + } + + if ycorner == "l" then { + newh := y - object.y + newh <:= MIN_H + } + else { + newh := object.h + object.y - y + newh <:= MIN_H + object.y +:= object.h - newh + } + + object.h := newh + object.w := neww + update_bb(object) + if object.w ~= neww & xcorner == "l" then + object.x +:= neww - object.w + if object.h ~= newh & ycorner == "u" then + object.y +:= newh - object.h + + VResize(object.v, object.x, object.y, object.w, object.h) + draw_outline(object) +end + +############################################################################ +# display_talk() is called to display the attribute sheets of the various +# object types. +############################################################################ +procedure display_talk(object) + case type(object) of { + "button_obj" : display_button_atts(object) + "slider_obj" : display_slider_atts(object) + "text_input_obj" : display_text_input_atts(object) + "rect_obj" : display_rect_atts(object) + "menu_obj" : display_menu_atts(object) + "line_obj" : display_line_atts(object) + "label_obj" : display_label_atts(object) + "radio_button_obj": display_radio_button_atts(object) + "list_obj" : display_list_atts(object) + } +end + +############################################################################ +# draw_object() is called to draw the various object types. +############################################################################ +procedure draw_object(object) + update_bb(object) + case type(object) of { + "sizer_obj" : draw_sizer(object) + "button_obj" : draw_button(object) + "text_input_obj" : draw_text_input(object) + "radio_button_obj" : draw_radio_button(object) + "rect_obj" : draw_rect(object) + "slider_obj" : draw_slider(object) + "line_obj" : draw_line(object) + "label_obj" : draw_label(object) + "menu_obj" : draw_menu(object) + "list_obj" : draw_list(object) + } +end + +############################################################################ +# erase_object() removes an object from the screen. +############################################################################ +procedure erase_object(object) + if type(object) == "line_obj" then + DrawGroove(APPWIN, object.x1, object.y1, object.x2, object.y2, 0) + else if type(object) == "button_obj" & \object.dflt then + EraseArea(APPWIN, object.x - 4, object.y - 4, object.w + 8, object.h + 8) + else + EraseArea(APPWIN, object.x, object.y, object.w, object.h) +end + +############################################################################ +# draw_focus() is called to draw focus lines around an object. +############################################################################ +procedure draw_focus(o) + if type(o) == "line_obj" then { + FillRectangle(XORWIN, o.x1 - 3, o.y1 - 3, 6, 6) + FillRectangle(XORWIN, o.x2 - 3, o.y2 - 3, 6, 6) + } else { + DrawLine(XORWIN, o.x-2, o.y+2, o.x-2, o.y-2, o.x+2, o.y-2) + DrawLine(XORWIN, o.x-2, o.y+o.h-3, o.x-2, o.y+o.h+1, o.x+2, o.y+o.h+1) + DrawLine(XORWIN, o.x+o.w-3, o.y-2, o.x+o.w+1, o.y-2, o.x+o.w+1, o.y+2) + DrawLine(XORWIN, + o.x+o.w-3, o.y+o.h+1, o.x+o.w+1, o.y+o.h+1, o.x+o.w+1, o.y+o.h-3) + } +end + +############################################################################ +# focus_object() sets the given object to be the object with the focus. +# Focus lines are drawn around the object and the FOCUS +# global is set to be the object. +############################################################################ +procedure focus_object(object) + unfocus_object(\FOCUS) + draw_focus(object) + object.focus := 1 + FOCUS := object + return object +end + +############################################################################ +# unfocus_object() unsets the focus. The focus lines are erased about +# the object and the FOCUS global is set to null. +############################################################################ +procedure unfocus_object(object) + draw_focus(object) + object.focus := 0 + FOCUS := &null + return object +end + +############################################################################ +# on_focus() returns either +# "lpt" : if object is a line and the mouse is on the left endpoint +# "rpt" : if object is a line and the mouse is on the right endpoint +# "ur" : if mouse is on upper-right focus point of object +# "ul" : if mouse is on upper-left focus point of object +# "lr" : if mouse is on lower-right focus point of object +# "ll" : if mouse is on lower-left focus point of object +# otherwise it fails +############################################################################ +procedure on_focus(object, x, y) + local range + + range := 5 + if type(object) == "line_obj" then { + if (object.x1 - range < x < object.x1 + range) & + (object.y1 - range < y < object.y1 + range) then + return "lpt" + else if (object.x2 - range < x < object.x2 + range) & + (object.y2 - range < y < object.y2 + range) then + return "rpt" + else fail + } + if (object.x+object.w-range) < x < (object.x+object.w+range) & + (object.y - range) < y < (object.y + range) then + return "ur" + if (object.x - range) < x < (object.x + range) & + (object.y - range) < y < (object.y + range) then + return "ul" + if (object.x - range) < x < (object.x + range) & + (object.y+object.h-range) < y < (object.y+object.h+range) then + return "ll" + if (object.x+object.w-range) < x < (object.x+object.w+range) & + (object.y+object.h-range) < y < (object.y+object.h+range) then + return "lr" + fail +end + +############################################################################ +# on_target() returns the object if the mouse is over the object. +# Else fails. +############################################################################ +procedure on_target(o, x, y) + local m, a, b, c, d + + if y < CANVASY then fail + if not ((o.x <= x <= o.x + o.w) & + (o.y <= y <= o.y + o.h)) then + fail + if type(o) == "line_obj" & o.w > 6 & o.h > 6 then { # if skewed line + # make sure (x,y) is reasonably close to the line + m := (o.y2 - o.y1) / real(o.x2 - o.x1) # slope + a := o.y1 - m * o.x1 # y-intercept + b := o.x1 - o.y1 / m # x-intercept + c := -a * o.x1 - b * o.y1 # ax + by + c = 0 + d := (a * x + b * y + c) / sqrt(a ^ 2 + b ^ 2) # distance + if abs(d) > 5 then + fail + } + return o +end + +############################################################################ +# object_of_event() checks the canvas object list against the mouse event +# coordinates to determine if the event correlates to +# a canvas object. If multiple objects match, the +# smallest is returned. (The area of a "line" is fudged.) +# Null is returned if the event does not correlate. +############################################################################ +procedure object_of_event(x, y) + local o, a, obj, area + + every o := !O_LIST do + if on_target(o, x, y) then { + if type(o) == "line_obj" then + a := 5 * maximum(o.w, o.h) + else + a := o.w * o.h + if /obj | a < area then { + obj := o + area := a + } + } + return obj +end + +############################################################################ +# clear_screen() empties the entire screen, redrawing just the palette +# and sizer object. The canvas list is emptied. +############################################################################ +procedure clear_screen() + O_LIST := list() + FOCUS := &null + DIRTY := &null + redraw_screen() +end + +############################################################################ +# redraw_screen() clears the screen and redraws both the palette and canvas. +############################################################################ +procedure redraw_screen() + EraseArea() + draw_header() + draw_canvas() +end + +############################################################################ +# shift_focus() moves the object with the FOCUS by in the amount given. +############################################################################ +procedure shift_focus(dx, dy) + local object + + if object := \FOCUS then { + unfocus_object(object) + move_object(object, object.x + dx, object.y + dy) + focus_object(object) + } +end + +############################################################################ +# copy_focus() makes a copy of the object with the focus. +############################################################################ +procedure copy_focus() + local r, drawin, temp, obj + + if obj := \FOCUS then { + unfocus_object(obj) + case type(obj) of { + "rect_obj": { + r := create_rect(obj.x + 10, obj.y + 10, obj.w, obj.h, obj.style) + } + "menu_obj": { + temp := copy(obj) + r := create_menu(obj.x + 10, obj.y + 10, obj.label, obj.style) + copy_menu(r, temp) + } + "button_obj": { + r := create_button(obj.x + 10, obj.y + 10, obj.w, obj.h, + obj.label, obj.style, obj.toggle) + } + "text_input_obj": { + r := create_text_input(obj.x + 10, obj.y + 10, + obj.label, obj.value, obj.length) + } + "label_obj": { + r := create_label(obj.x + 10, obj.y + 10, obj.label) + } + "radio_button_obj": { + r := create_radio_button(obj.x + 10, obj.y + 10, copy(obj.alts)) + } + "slider_obj": { + r := create_slider(obj.x + 10, obj.y + 10, obj.w, obj.h, + obj.typ, obj.min, obj.max, obj.value, obj.filter) + } + "line_obj": { + r := create_line(obj.x1 + 10, obj.y1 + 10, obj.x2 + 10, obj.y2 + 10) + } + "list_obj": { + r := create_list(obj.x + 10, obj.y + 10, obj.w, obj.h, + obj.style, obj.scroll) + } + default: return + } + push(O_LIST, r) + draw_object(r) + focus_object(r) + DIRTY := 1 + } +end + +############################################################################ +# delete_focus() removes the object with the FOCUS from the canvas list. +############################################################################ +procedure delete_focus() + local i + + if \FOCUS then { + draw_focus(FOCUS) + erase_object(FOCUS) + DELETED := FOCUS + every i := 1 to *O_LIST do + if (O_LIST[i] === FOCUS) then + O_LIST := O_LIST[1:i] ||| O_LIST[i+1:*O_LIST+1] + FOCUS := &null + DELETED.focus := 0 + DIRTY := 1 + draw_overlap(DELETED) + } +end + +############################################################################ +# undelete() restores the most recently deleted object. +############################################################################ +procedure undelete() + if \DELETED then { + unfocus_object(\FOCUS) + push(O_LIST, DELETED) + draw_object(DELETED) + focus_object(DELETED) + DELETED := &null + DIRTY := 1 + } +end + +############################################################################ +# add_palette_entry() adds one entry to the palette +############################################################################ +procedure add_palette_entry(name, bwimage, colrimage) + static x + initial x := 0 + + push(P_LIST, palette_obj(name, x, MENUBAR.ah + 3, bwimage, colrimage)) + x +:= PAL_W +end + +############################################################################ +# draw_decor() redraws the decorative lines that extend across the window. +############################################################################ +procedure draw_decor() + DrawLine(0, MENUBAR.ah, 2000, MENUBAR.ah) + DrawLine(0, CANVASY-1, 2000, CANVASY-1) +end + +############################################################################ +# draw_header() redraws the window header. +############################################################################ +procedure draw_header() + local e, xpad, ypad, w, d, h, im + + MENUBAR.V.draw(MENUBAR) + DrawString(SELECT.ax + 4, SELECT.ay + 15, "Select") + BevelRectangle(SELECT.ax, SELECT.ay, SELECT.aw, SELECT.ah) + draw_decor() + every e := !P_LIST do { + if WAttrib("depth") > 1 then (im := e.colrimage) ? { + w := tab(upto(',')) # width of image + move(1) + tab(upto(',') + 1) # skip over palette spec + h := *tab(0) / w # height of image + } + else (im := e.bwimage) ? { + w := tab(upto(',')) # width of image + d := ((w + 3) / 4) # digits per row + move(2) + h := *tab(0) / d # height of image + } + xpad := (PAL_W - w) / 2 + ypad := (PAL_H - h) / 2 + DrawImage(e.x + xpad, e.y + ypad, im) + } +end + +############################################################################ +# draw_canvas() draws all the objects that exist within the canvas. +############################################################################ +procedure draw_canvas() + every draw_object(O_LIST[*O_LIST to 1 by -1]) + draw_sizer(SIZER) + draw_focus(\FOCUS) +end + +############################################################################ +# draw_overlap() draws any objects that overlap the argument object. +############################################################################ +procedure draw_overlap(object) + local f, o, d + + if type(object) == "button_obj" & \object.dflt then + d := 8 # fudge factor for default box on both objects + else + d := 4 # only the other object can have default box + + unfocus_object(f := \FOCUS) + every o := O_LIST[*O_LIST to 1 by -1] do { + if o.x >= object.x + object.w + d then next + if object.x >= o.x + o.w + d then next + if o.y >= object.y + object.h + d then next + if object.y >= o.y + o.h + d then next + if o === object then next + draw_object(o) + } + if object.x + object.w + d >= SIZER.x | + object.y + object.h + d >= SIZER.y then + draw_sizer(SIZER) + focus_object(\f) +end + +############################################################################ +# palette_object_of_event() cycles through the list of palette objects +# to determine if any of them were the target +# of a mouse event. +############################################################################ +procedure palette_object_of_event(x, y) + local o + + every o := !P_LIST do + if o.x <= x <= o.x + PAL_W & o.y <= y <= o.y + PAL_H then + return o + return &null +end + +############################################################################ +# create_object_instance() creates an instance of the given object. +############################################################################ +procedure create_object_instance(obj) + local r, temp, x, y, w, h + + x := &x + y := CANVASY + w := 32 + h := 20 + case obj.name of { + "line": + r := create_line(x, y + 3, x + PAL_W, y + 3) + "rect": + r := create_rect(x, y, w, h, "grooved") + "menu": { + r := create_menu(x, y, "Menu", "pull") + add_item(r, "three", 0) + add_item(r, "two", 0) + add_item(r, "one", 0) + } + "button": + r := create_button(x, y, w, h, "push") + "radio_button": + r := create_radio_button(x, y, ["one","two","three"]) + "text": + r := create_text_input(x, y, "Text:", "", 3) + "label": + r := create_label(x, y, "Label") + "slider": + r := create_slider(x, y, VSlider_DefWidth, VSlider_DefLength, + "Slider", 0.0, 1.0, 0.5, 1) + "scroll": + r := create_slider(x, y, VSlider_DefWidth, VSlider_DefLength, + "Scrollbar", 0.0, 1.0, 0.5, 1) + "list": + r := create_list(x, y) + default: return &null + } + push(O_LIST, r) + DIRTY := 1 + return r +end + +############################################################################ +# create_palette() creates the palette objects. +############################################################################ +procedure create_palette() + + add_palette_entry("button", + "25,#1ffffff10000011000001115555110aaaa11155551100000110000011ffffff", + "25,c1,_ + 6666666666666666666666666_ + 6~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~222222222222222~~~~1_ + 6~~~~222222222222222~~~~1_ + 6~~~~222222222222222~~~~1_ + 6~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~~~~~~~~~~~~~~~~~~~~1_ + 6111111111111111111111111_ + ") + add_palette_entry("radio_button", + "32,#FFFFFFFF8000000180000021800000518555508982AAA1058555508980000051_ + 80000021800000018000000180000021800000518555508982AAA10585555089_ + 800000518000002180000001800000018000002180000071855550F982AAA1FD_ + 855550F9800000718000002180000001FFFFFFFF", + "33,c1,_ + 666666666666666666666666666666661_ + 6~~~~~6~~~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~666~~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~66~66~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~66~~~66~~~222222222222222~~~~1_ + 6~66~~~~~66~~222222222222222~~~~1_ + 6~~11~~~11~~~222222222222222~~~~1_ + 6~~~11~11~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~111~~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~~1~~~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~~6~~~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~666~~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~66~66~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~66~~~66~~~222222222222222~~~~1_ + 6~66~~~~~66~~222222222222222~~~~1_ + 6~~11~~~11~~~222222222222222~~~~1_ + 6~~~11~11~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~111~~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~~1~~~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~~6~~~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~666~~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~66066~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~6600066~~~222222222222222~~~~1_ + 6~660000066~~222222222222222~~~~1_ + 6~~1100011~~~222222222222222~~~~1_ + 6~~~11011~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~111~~~~~~~~~~~~~~~~~~~~~~~~1_ + 6~~~~~1~~~~~~~~~~~~~~~~~~~~~~~~~1_ + 611111111111111111111111111111111_ + ") + add_palette_entry("menu", + "20,#1ffff1ffff1d5571eaaf1d5571fffffffff800018000180001955518aaa98000_ + 18000180001955518aaa9800018000180001955518aaa9800018000180001955_ + 518aaa98000180001fffff", + "20,c1,_ + 1111111111111116~~~~_ + 1000000000000006~~~~_ + 1005555555550006~~~~_ + 1005555555550006~~~~_ + 1000000000000006~~~~_ + 1000000000000006~~~~_ + 66666666666666666666_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~22222222222222~~1_ + 6~~22222222222222~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~22222222222222~~1_ + 6~~22222222222222~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~22222222222222~~1_ + 6~~22222222222222~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~22222222222222~~1_ + 6~~22222222222222~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 6~~~~~~~~~~~~~~~~~~1_ + 61111111111111111111_ + ") + add_palette_entry("list", + "32,#FFFFFFFF92000001AA000001AA555551C62AAAA9FE0000018200000182555551_ + FE2AAAA9C6000001C7FFFFFFC7AAAAAFC7D55557C7FFFFFFC6000001C6555551_ + C62AAAA9FE0000018200000182555551822AAAA9820000018200000182555551_ + 822AAAA982000001FE000001C6555551AA2AAAA9AA00000192000001FFFFFFFF", + "32,c1,_ + 111111111111111111111111~1111111_ + 1~~~~~~~~~~~~~~~~~~~~~~6~1~~6~~6_ + 1~~~~~~~~~~~~~~~~~~~~~~6~1~6~1~6_ + 1~~222222222222222222~~6~1~6~1~6_ + 1~~222222222222222222~~6~16~~~16_ + 1~~~~~~~~~~~~~~~~~~~~~~6~1611116_ + 1~~~~~~~~~~~~~~~~~~~~~~6~1~~~~~6_ + 1~~222222222222222222~~6~1666666_ + 1~~222222222222222222~~6~16~~~16_ + 1~~~~~~~~~~~~~~~~~~~~~~6~16~~~16_ + 100000000000000000000006~16~~~16_ + 100222222222222222222006~16~~~16_ + 100222222222222222222006~16~~~16_ + 100000000000000000000006~16~~~16_ + 1~~~~~~~~~~~~~~~~~~~~~~6~16~~~16_ + 1~~222222222222222222~~6~16~~~16_ + 1~~222222222222222222~~6~1611116_ + 1~~~~~~~~~~~~~~~~~~~~~~6~1~~~~~6_ + 1~~~~~~~~~~~~~~~~~~~~~~6~1~~~~~6_ + 1~~222222222222222222~~6~1~~~~~6_ + 1~~222222222222222222~~6~1~~~~~6_ + 1~~~~~~~~~~~~~~~~~~~~~~6~1~~~~~6_ + 1~~~~~~~~~~~~~~~~~~~~~~6~1~~~~~6_ + 1~~222222222222222222~~6~1~~~~~6_ + 1~~222222222222222222~~6~1~~~~~6_ + 1~~~~~~~~~~~~~~~~~~~~~~6~1666666_ + 1~~~~~~~~~~~~~~~~~~~~~~6~16~~~16_ + 1~~222222222222222222~~6~16~~~16_ + 1~~222222222222222222~~6~1~6~1~6_ + 1~~~~~~~~~~~~~~~~~~~~~~6~1~6~1~6_ + 1~~~~~~~~~~~~~~~~~~~~~~6~1~~6~~6_ + 16666666666666666666666641666666_ + ") + add_palette_entry("text", + "32,#ffffc00080004000800040008000400080004555800042aa9ffe455580004000_ + 80004000ffffc000", + "32,c1,_ + ~~~~~~~~~~~~~~111111111111111111_ + ~~~~~~~~~~~~~~1~~~~~~~~~~~~~~~~6_ + ~~~~~~~~~~~~~~1~~~~~~~~~~~~~~~~6_ + ~~~~~~~~~~~~~~1~~~~~~~~~~~~~~~~6_ + 22222222222~~~1~~~~~~~~~~~~~~~~6_ + 22222222222~~~1~~~~~~~~~~~~~~~~6_ + 22222222222~~~1~~~~~~~~~~~~~~~~6_ + ~~~~~~~~~~~~~~1~~~~~~~~~~~~~~~~6_ + ~~~~~~~~~~~~~~1~~~~~~~~~~~~~~~~6_ + ~~~~~~~~~~~~~~166666666666666666_ + ") + add_palette_entry("slider", + "9,#1FF1011011011011011011011011011011FF1831831831831831FF_ + 1831831831831831FF1011011011011011011011FF", + "9,c1,_ + 111111111_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 166666666_ + 16~~~~~16_ + 16~~~~~16_ + 16~~~~~16_ + 16~~~~~16_ + 16~~~~~16_ + 161111116_ + 166666616_ + 16~~~~~16_ + 16~~~~~16_ + 16~~~~~16_ + 16~~~~~16_ + 16~~~~~16_ + 161111116_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 166666666_ + ") + add_palette_entry("scroll", + "9,#1FF1111291291451451FF1011011011011FF1831831831831831FF_ + 1011011011011011011011FF1451451291291111FF", + "9,c1,_ + 111111111_ + 1~~~6~~~6_ + 1~~6~1~~6_ + 1~~6~1~~6_ + 1~6~~~1~6_ + 1~6~~~1~6_ + 16~~~~~16_ + 161111116_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 166666666_ + 16~~~~~16_ + 16~~~~~16_ + 16~~~~~16_ + 16~~~~~16_ + 16~~~~~16_ + 161111116_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 1~~~~~~~6_ + 166666666_ + 16~~~~~16_ + 1~6~~~1~6_ + 1~6~~~1~6_ + 1~~6~1~~6_ + 1~~6~1~~6_ + 1~~~6~~~6_ + 166666666_ + ") + add_palette_entry("rect", + "32,#ffffffff80000001800000018000000180000001800000018000000180000001_ + 8000000180000001800000018000000180000001800000018000000180000001_ + 800000018000000180000001ffffffff", + "32,c1,_ + 33333333333333333333333333333333_ + 36666666666666666666666666666666_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36~~~~~~~~~~~~~~~~~~~~~~~~~~~~36_ + 36333333333333333333333333333336_ + 36666666666666666666666666666666_ + ") + add_palette_entry("label", + "13,#0040004000e000e000e001b00190019003180308030807fc060406040c061e0f", + "13,c1,_ + ~~~~~~0~~~~~~_ + ~~~~~~0~~~~~~_ + ~~~~~000~~~~~_ + ~~~~~000~~~~~_ + ~~~~~000~~~~~_ + ~~~~00~00~~~~_ + ~~~~0~~00~~~~_ + ~~~~0~~00~~~~_ + ~~~00~~~00~~~_ + ~~~0~~~~00~~~_ + ~~~0~~~~~0~~~_ + ~~000000000~~_ + ~~0~~~~~~00~~_ + ~~0~~~~~~00~~_ + ~00~~~~~~~00~_ + 0000~~~~~0000_ + ") + add_palette_entry("line", + "32,#0000000f0000000f0000001f0000006f00000180000006000000180000006000_ + 0001800000060000001800000060000001800000f6000000f8000000f0000000f0000000", + "30,c1,_ + ~~~~~~~~~~~~~~~~~~~~~~~~~~0000_ + ~~~~~~~~~~~~~~~~~~~~~~~~~~3300_ + ~~~~~~~~~~~~~~~~~~~~~~~~336600_ + ~~~~~~~~~~~~~~~~~~~~~~33660000_ + ~~~~~~~~~~~~~~~~~~~~3366~~~~~~_ + ~~~~~~~~~~~~~~~~~~3366~~~~~~~~_ + ~~~~~~~~~~~~~~~~3366~~~~~~~~~~_ + ~~~~~~~~~~~~~~3366~~~~~~~~~~~~_ + ~~~~~~~~~~~~3366~~~~~~~~~~~~~~_ + ~~~~~~~~~~3366~~~~~~~~~~~~~~~~_ + ~~~~~~~~3366~~~~~~~~~~~~~~~~~~_ + ~~~~~~3366~~~~~~~~~~~~~~~~~~~~_ + 00003366~~~~~~~~~~~~~~~~~~~~~~_ + 003366~~~~~~~~~~~~~~~~~~~~~~~~_ + 0066~~~~~~~~~~~~~~~~~~~~~~~~~~_ + 0000~~~~~~~~~~~~~~~~~~~~~~~~~~_ + ") +end diff --git a/ipl/gpacks/vib/vibfile.icn b/ipl/gpacks/vib/vibfile.icn new file mode 100644 index 0000000..da1dd43 --- /dev/null +++ b/ipl/gpacks/vib/vibfile.icn @@ -0,0 +1,603 @@ +############################################################################ +# +# vibfile.icn -- procedures for reading and writing specs to files +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$include "vibdefn.icn" +$include "vdefns.icn" + +############################################################################ +# constants and globals that are used only in this file: +############################################################################ +$define PTITLE "#===<<vib prototype file>>===" +$define HEADER "#===<<vib:begin>>===\tmodify using vib; do not remove this marker line" +$define TRAILER "#===<<vib:end>>===\tend of section maintained by vib" +$define XHEADER "#===<<xie:begin>>===" # for detecting old files +$define XTRAILER "#===<<xie:end>>===" +$define HMATCH 20 # number of chars that must match in header +$define TMATCH 18 # number of chars that must match in trailer +global USER_PREFIX, # user code preceding spec + USER_SUFFIX # user code following spec + +############################################################################ +# new_session() creates a new, empty VIB session +############################################################################ +procedure new_session() + local fname + + if not flush_session() then fail + SIZER := create_sizer() + clear_screen() + SESSION := newname() + label_session() + USER_PREFIX := USER_SUFFIX := &null + return +end + +############################################################################ +# load_session() reads in a saved VIB session file so that it can be +# re-edited. +############################################################################ +procedure load_session(s) + local line, ifile, l, o + + ifile := open(s, "r") | fail + clear_screen() + + USER_PREFIX := USER_SUFFIX := "" + while line := read(ifile) do { + if line ? match((HEADER | XHEADER)[1 +: HMATCH]) then + break + if line ? match("# Session Code:") then { + Notice("Old file format; use uix to convert") + USER_PREFIX := USER_SUFFIX := &null + fail + } + USER_PREFIX ||:= line + USER_PREFIX ||:= "\n" + line := &null + } + + DIRTY := &null + if not (\line ? match((HEADER | XHEADER)[1 +: HMATCH])) then { + Notice("No interface section found; creating one") + USER_PREFIX ||:= "\n\n\n" + DIRTY := 1 + } + + while o := load_object(ifile) do case o.typ of { + "Button" : init_object(load_button, button_obj(), o) + "Text" : init_object(load_text_input, text_input_obj(), o) + "Scrollbar" : init_object(load_slider, slider_obj(), o) + "Slider" : init_object(load_slider, slider_obj(), o) + "Line" : init_object(load_line, line_obj(), o) + "Rect" : init_object(load_rect, rect_obj(), o) + "Label" : init_object(load_label, label_obj(), o) + "Message" : init_object(load_label, label_obj(), o) + "Choice" : init_object(load_radio_button, radio_button_obj(), o) + "Menu" : init_object(load_menu, menu_obj(), o) + "Sizer" : init_object(load_sizer, sizer_obj(), o) + "Check" : init_object(load_xbox, button_obj(), o) + "List" : init_object(load_list, list_obj(), o) + } + + while USER_SUFFIX ||:= read(ifile) do + USER_SUFFIX ||:= "\n" + close(ifile) + return +end + +############################################################################# +# init_object() initializes an object record and calls a proc to register it. +############################################################################# +procedure init_object(proc, r, o) + r.id := o.id + r.proc := o.proc + r.x := integer(o.x) + r.y := o.y + CANVASY + r.w := integer(o.w) + r.h := integer(o.h) + r.focus := 0 + push(O_LIST, r) # must precede proc call + proc(r, o) # call object-specific procedure + update_bb(r) + draw_object(r) +end + +############################################################################ +# load_object() reads the next object from a saved session file. +############################################################################ +procedure load_object(f) + local c, s, l, r + + # find a line where the first nonblank character is a "[" + repeat { + while (c := reads(f, 1)) & upto(' \t\f', c) + if \c == "[" then + break + s := (c || read(f)) | fail + if s ? match((TRAILER | XTRAILER)[1 +: TMATCH]) then + fail + } + + # load the list of values + l := load_strings(f) | fail + + # break them down into an ext_rec record + r := ext_rec() + s := get(l) | fail + s ? { + r.id := tab(upto(':')) | fail; move(1) + r.typ := tab(upto(':')) | fail; move(1) + r.sty := tab(upto(':')) | fail; move(1) + r.num := tab(upto(':')) | fail; move(1) + r.x := tab(upto(',')) | fail; move(1) + r.y := tab(upto(',')) | fail; move(1) + r.w := tab(upto(',')) | fail; move(1) + r.h := tab(upto(':')) | fail; move(1) + r.lbl := tab(0) + } + r.proc := get(l) | "" + r.etc := get(l) | [] + return r +end + +############################################################################ +# load_strings() reads a list of strings after "[" has already been consumed. +############################################################################ +procedure load_strings(f) + local l, c, s, n + + l := [] + n := 0 + while c := reads(f, 1) do case c of { + + "]": return l # end of list + ",": (n <:= *l) | put(l, &null) + " ": next # whitespace: do nothing + "\t": next + "\r": next + "\n": next + "[": put(l, load_strings(f)) # nested list + + "\"": { # string constant + s := "" + while (c := reads(f, 1)) & not upto('"\n"', c) do + if s == "\\" then + s ||:= reads(f, 1) + else + s ||:= c + put(l, s) + } + + default: { # anything else: consume to separator + s := c + while (c := reads(f, 1)) & not upto(',] \t\r\n', c) do + s ||:= c + put(l, s) + if c == "]" then + return l + } + } + + fail # EOF hit +end + +############################################################################ +# save_session() saves the current session to a file. If "pflag" is set, +# the standard prefix is used (for prototype mode). +############################################################################ +procedure save_session(s, pflag) + local ofile + + sanity_check() | fail + ofile := open(s, "w") + if /ofile then { + Notice("Could not open " || s, "(FILE WAS NOT SAVED)") + fail + } + if /SIZER.dlog then + save_app(ofile, pflag, s) + else + save_dlog(ofile, pflag, s) + close(ofile) + if /pflag then + DIRTY := &null + return +end + +############################################################################ +# sanity_check() issues warnings if certain things don't look right. +############################################################################ +procedure sanity_check() + local messages, npush, ndflt, nrect, nlist, o + + messages := [] + npush := ndflt := nrect := nlist := 0 + every o := !O_LIST do { + case type(o) of { + "button_obj": { + if /o.toggle then npush +:= 1 + if \o.dflt then ndflt +:= 1 + } + "rect_obj": { + nrect +:= 1 + } + "list_obj": { + nlist +:= 1 + } + } + } + + if \SIZER.dlog then { + if ndflt > 1 then + put(messages, "", + "More than one button is marked as the default.", + "Only one will be used.") + if npush = 0 then + put(messages, "", + "There is no non-toggle button, so it will not", + "be possible to dismiss the dialog box.") + if nrect > 0 | nlist > 0 then + put(messages, "", + "There are one or more regions or text lists,", + "but these do not function in dialog boxes.") + } + else { + if ndflt > 0 then + put(messages, "", + "A button is marked as a dialog default,", + "but this is not a dialog specification.") + } + + if *messages = 0 then + return + + push(messages, "Warning:") + case TextDialog(messages, , , , ["Continue", "Cancel"], 2) of { + "Continue": return + "Cancel": fail + } +end + +############################################################################ +# save_app() saves the session as an application. If "pflag" is set, +# the standard prefix is used (for prototype mode). +############################################################################ +procedure save_app(ofile, pflag, filename) + local id + + id := ("" ~== \SIZER.id) | "ui" + + if \pflag then + write(ofile, PTITLE, "\n\n") + if \pflag | /USER_PREFIX then { + if /pflag then + ipl_header(ofile, filename, "Program to", "vsetup") + app_prologue(ofile, id, pflag) + if /pflag then + save_procs(ofile) + } + else + writes(ofile, USER_PREFIX) + + write(ofile, HEADER) + write(ofile, "procedure ", id, "_atts()") + writes(ofile, " return [\"size=", SIZER.x + SIZER.w, ",", + SIZER.y - CANVASY + SIZER.h, "\", \"bg=", VBackground, "\"") + writes(ofile, ", \"label=", "" ~== SIZER.label, "\"") + write(ofile, "]") + write(ofile,"end") + write(ofile) + write(ofile, "procedure ", id, "(win, cbk)") + write(ofile, "return vsetup(win, cbk,") + output_spec(ofile, SIZER) + output_all(ofile, O_LIST) + write(ofile, " )") + write(ofile, "end") + write(ofile, TRAILER) + + if /pflag & \USER_SUFFIX then + writes(ofile, USER_SUFFIX) + return +end + +############################################################################ +# save_procs() generates empty callback procedures in lexical order. +############################################################################ +procedure save_procs(ofile) + local o, t, l + + t := table() + every o := !O_LIST do + t["" ~== \o.proc] := o + l := sort(t, 3) + while get(l) do { + o := get(l) + writes(ofile, "procedure ", o.proc, "(vidget, ") + if type(o) == "rect_obj" then + write(ofile, "e, x, y)") + else + write(ofile, "value)") + write(ofile, " return") + write(ofile, "end") + write(ofile) + } + return +end + +############################################################################ +# save_dlog() saves the session as a dialog. If "pflag" is set, +# the standard prefix is used (for prototype mode). +############################################################################ +procedure save_dlog(ofile, pflag, filename) + local id + + id := ("" ~== \SIZER.id) | "dl" + + if \pflag then + dlog_prototype(ofile, id) + else if /USER_PREFIX then { + ipl_header(ofile, filename, "Procedure to", "dsetup") + dlog_prologue(ofile) + } + else + writes(ofile, USER_PREFIX) + + write(ofile, HEADER) + write(ofile, "procedure ", id, "(win, deftbl)") + write(ofile, "static dstate") + write(ofile, "initial dstate := dsetup(win,") + output_spec(ofile, SIZER) + output_all(ofile, O_LIST) + write(ofile, " )") + write(ofile, "return dpopup(win, deftbl, dstate)") + write(ofile, "end") + write(ofile, TRAILER) + + if /pflag & \USER_SUFFIX then + writes(ofile, USER_SUFFIX) + return +end + +############################################################################ +# output_all() outputs the members of an object list, sorted by ID, +# but with rectangles last so that they can enclose other objects. +############################################################################ +record output_rec(obj, key) + +procedure output_all(f, l) + local t, e, k + + t := [] + every e := !l do { + if type(e) == "rect_obj" then + k := "~" || right(e.w * e.h, 20) || e.id # rects last, by area + else + k := e.id + put(t, output_rec(e, k)) + } + t := sortf(t, 2) + every e := !t do + output_spec(f, e.obj) + return +end + +############################################################################ +# output_spec() outputs the spec for an object. +############################################################################ +procedure output_spec(f, o) + local r + + # set standard fields + r := ext_rec(o) + r.id := o.id + r.proc := o.proc + r.x := o.x + r.y := o.y - CANVASY + r.w := o.w + r.h := o.h + # set type-dependent fields + case type(o) of { + "sizer_obj" : save_sizer(r, o) + "button_obj" : save_button(r, o) + "text_input_obj" : save_text_input(r, o) + "line_obj" : save_line(r, o) + "rect_obj" : save_rect(r, o) + "slider_obj" : save_slider(r, o) + "radio_button_obj" : save_radio_button(r, o) + "label_obj" : save_label(r, o) + "menu_obj" : save_menu(r, o) + "list_obj" : save_list_obj(r, o) + } + writes(f, " [\"") + writes(f, r.id, ":", r.typ, ":", r.sty, ":", r.num, ":") + writes(f, r.x, ",", r.y, ",", r.w, ",", r.h, ":") + writes(f, r.lbl, "\",") + if /SIZER.dlog then + writes(f, r.proc) + if \r.etc then + output_list(f, r.etc) + write(f, "],") + return +end + +############################################################################ +# output_list() outputs a list in Icon form preceded by ",\n". +############################################################################ +procedure output_list(f, a) + local prefix, elem, n + static indent + initial indent := " " + + n := 0 + indent ||:= " " + writes(f, ",\n", indent, "[") + prefix := "" + while elem := get(a) do + if type(elem) == "list" then { + output_list(f, elem) + prefix := ",\n" || indent + n := 0 + } + else { + writes(f, prefix, image(elem)) + if (n +:= 1) % 5 = 0 then + prefix := ",\n" || indent + else + prefix := "," + } + writes(f, "]") + indent := indent[1:-3] +end + +############################################################################ +# prototype() saves, compiles, and executes the current session. +############################################################################ +procedure prototype() + local f, line + + if f := open(PROTOFILE) then { + line := read(f) + close(f) + if \line & not (line ? =PTITLE) then { + Notice("Cannot create prototype file " || PROTOFILE || ":", + "it already contains something that is not a VIB prototype") + fail + } + } + + # write source file + if save_session(PROTOFILE, 1) then { + # translate and execute + WAttrib("pointer=" || ("wait" | "watch")) + system(BUILDPROTO) + remove(PROTOFILE) + WAttrib("pointer=" || ("left ptr" | "arrow")) + system(EXECPROTO) + } +end + +############################################################################ +# newname() invents a name when creating a new file. +############################################################################ +procedure newname() + local s, i, f + + every i := seq() do { + s := "app" || i || ".icn" # invent "app<n>.icn" file name + if f := open(s) then + close(f) # can't use this name; already exists + else + return s # found a safe new name + } +end + +############################################################################ +# ipl_header() writes a standard IPL application header. +############################################################################ +procedure ipl_header(ofile, filename, subject, links) + local hline, date + + hline := repl("#", 76) + &dateline ? { + tab(upto(',') + 2) + date := tab(upto(',') + 6) + } + + write(ofile, hline) + write(ofile, "#\n#\tFile: ", filename) + write(ofile, "#\n#\tSubject: ", subject, " ...") + write(ofile, "#\n#\tAuthor: ") + write(ofile, "#\n#\tDate: ", date) + write(ofile, "#\n", hline) + write(ofile, "#\n#\n#\n", hline) + write(ofile, "#\n# Requires:\n#\n", hline) + write(ofile, "#\n# Links: ", links) + write(ofile, "#\n", hline) + write(ofile) + return +end + +############################################################################ +# app_prologue() writes a main program and other code for a new application. +############################################################################ +procedure app_prologue(f, id, pflag) + local vecho, e + + if \pflag then + vecho := ", VEcho" + else + vecho := "" + + every write(f, ![ + "# This vib interface specification 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.", + "", + "link vsetup", + "", + "procedure main(args)", + " local vidgets, root, paused", + "", + " (WOpen ! " || id || "_atts()) | stop(\"can't open window\")", + " vidgets := " || id || "(" || vecho || ")\t\t\t\t# set up vidgets", + " root := vidgets[\"root\"]" + ]) + + # generate a sample VSetItems call for every list object (prototyping only) + if \pflag then + every e := !O_LIST do + if type(e) == "list_obj" then + write(f, " VSetItems(vidgets[\"", e.id, + "\"], [\"a\", \"b\", \"c\", \"d\"])"); + + every write(f, ![ + "", + " paused := 1\t\t\t\t\t# flag no work to do", + " repeat {", + " # handle any events that are available, or", + " # wait for events if there is no other work to do", + " while (*Pending() > 0) | \\paused do {", + " ProcessEvent(root, QuitCheck)", + " }", + " # if <paused> is set null, code can be added here", + " # to perform useful work between checks for input", + " }", + "end", + ""]) +end + +############################################################################ +# dlog_prologue() writes a header for a dialog file. +############################################################################ +procedure dlog_prologue(f) +every write(f, ![ + "# Link this dialog specification with the rest of your program code.", + "# Use vib to make any changes.", + "", + "link dsetup", + ""]) +end + +############################################################################ +# dlog_prototype() writes a header for a dialog prototyping run. +############################################################################ +procedure dlog_prototype(f, id) + write(f, PTITLE) + write(f) + write(f, "link dsetup, graphics") + write(f) + write(f, "procedure main(args)") + write(f, " remove(", image(PROTOEXE), ")") + write(f, " dproto(", id, ", , ", + SIZER.x + SIZER.w, ", ", SIZER.y - CANVASY + SIZER.h, ", args)") + write(f, "end") + write(f) +end diff --git a/ipl/gpacks/vib/vibglbl.icn b/ipl/gpacks/vib/vibglbl.icn new file mode 100644 index 0000000..e226fe8 --- /dev/null +++ b/ipl/gpacks/vib/vibglbl.icn @@ -0,0 +1,38 @@ +############################################################################ +# +# vibglbl.icn -- global variables +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +global SESSION # name of current editing session (file name) +global DIRTY # dirty bit to inform user of unsaved changes +global ALIGN # flag indicating current state of align mode + +global XORWIN # &window clone clone with "drawop=reverse" +global APPWIN # &window clipped to application area +global DRAGWIN # clone with dark background, for dragging + +global CANVASY # offset to app coordinate system (below menu bar) +global PAD # vertical spacing in dialog boxes + +global ROOT # root frame for vidgets +global MENUBAR # vidget for VIB's menu bar +global SELECT # vidget for "Select" pseudo-menu button + +global P_LIST # list of palette objects +global O_LIST # list of graphical object instances +global SIZER # sizer object that gets dragged around the canvas + +global FOCUS # current object of focus (if any) +global DELETED # last object deleted (if any) + +global LBMASK # cset of chars allowed in object label +global IDMASK # cset of chars allowed in object index (table key) +global CBMASK # cset of chars allowed in callback or other Icon ID + +# external representation record +record ext_rec(id, typ, sty, num, x, y, w, h, lbl, proc, etc) diff --git a/ipl/gpacks/vib/viblabel.icn b/ipl/gpacks/vib/viblabel.icn new file mode 100644 index 0000000..54e71dd --- /dev/null +++ b/ipl/gpacks/vib/viblabel.icn @@ -0,0 +1,125 @@ +############################################################################ +# +# viblabel.icn -- procedures for defining a label object +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$include "vibdefn.icn" + +########################################################################## +# label_obj: +# v : vidget used for drawing label +# proc : name of user callback procedure (unused for a label) +# id : unique means of identifying instance +# x,y,w,h : bounding box +# label : label itself +# focus : should focus lines be drawn around this object? +########################################################################## +record label_obj(v, proc, id, x, y, w, h, label, focus) + +########################################################################## +# create_label() creates a label instance and draws the label if +# it is a first class object. +########################################################################## +procedure create_label(x, y, label) + local r, id + + id := next_id("label") + r := label_obj(, "", "label" || id, x, y, 0, 0, label, 0) + r.v := Vmessage(ROOT, x, y, APPWIN, label) + VRemove(ROOT, r.v, 1) + return r +end + +########################################################################## +# draw_label() draws the given label instance. +########################################################################## +procedure draw_label(r) + r.v.s := r.label + VDraw(r.v) +end + +########################################################################## +# update_label_bb() disallows resizing of a label. +########################################################################## +procedure update_label_bb(object) + object.w := TextWidth(APPWIN, object.label) + object.h := WAttrib(APPWIN, "fheight") +end + +########################################################################## +# load_label() restores a label object from session code. +########################################################################## +procedure load_label(r, o) + r.label := o.lbl + r.v := Vmessage(ROOT, r.x, r.y, APPWIN, r.label) + VRemove(ROOT, r.v, 1) +end + +########################################################################## +# save_label() augments the record for saving a label object. +########################################################################## +procedure save_label(r, o) + r.typ := "Label" + r.lbl := image(o.label)[2:-1] + return +end + +########################################################################## +# display_label_atts() displays the attribute sheet with the current +# attributes for the given label instance. +########################################################################## +procedure display_label_atts(object) + local t + + t := table() + t["a_label"] := object.label + t["b_id"] := object.id + t["c_x"] := object.x + t["d_y"] := object.y - CANVASY + + repeat { + if label_dialog(t) == "Cancel" then + fail + + if illegal(t["a_label"], "Label", "l") | + illegal(t["b_id"], "ID", "s") | + illegal(t["c_x"], "X", "i") | + illegal(t["d_y"], "Y", "i") + then + next + + if *t["a_label"] = 0 then { + Notice("Label value must be specified") + next + } + + object.label := t["a_label"] + object.id := t["b_id"] + + unfocus_object(object) + move_object(object, t["c_x"], t["d_y"] + CANVASY) + focus_object(object) + break + } +end + +#===<<vib:begin>>=== modify using vib; do not remove this marker line +procedure label_dialog(win, deftbl) +static dstate +initial dstate := dsetup(win, + ["label_dialog:Sizer::1:0,0,460,180:",], + ["_cancel:Button:regular::250,120,50,30:Cancel",], + ["_okay:Button:regular:-1:180,120,50,30:Okay",], + ["a_label:Text::50:13,14,430,19:label: \\=",], + ["b_id:Text::40:13,35,360,19:ID: \\=",], + ["c_x:Text::3:13,62,101,19: x: \\=",], + ["d_y:Text::3:13,83,101,19: y: \\=",], + ) +return dpopup(win, deftbl, dstate) +end +#===<<vib:end>>=== end of section maintained by vib diff --git a/ipl/gpacks/vib/vibline.icn b/ipl/gpacks/vib/vibline.icn new file mode 100644 index 0000000..16f3d89 --- /dev/null +++ b/ipl/gpacks/vib/vibline.icn @@ -0,0 +1,197 @@ +############################################################################ +# +# vibline.icn -- procedures for defining a line object +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$include "vibdefn.icn" + +########################################################################## +# line_obj: +# proc : name of user callback procedure +# v : vidget used for drawing line +# id : unique means of identifying instance +# x,y,w,h : bounding box +# x1,y1 : one endpoint +# y1,y2 : other endpoint +# focus : should focus lines be drawn around this object? +########################################################################## +record line_obj(v, proc, id, x, y, w, h, x1, y1, x2, y2, focus) + +########################################################################## +# create_line() creates a line instance and draws the line if +# it is a first class object. +########################################################################## +procedure create_line(x1, y1, x2, y2) + local r, id + + id := next_id("line") + r := line_obj(, "", "line" || id, , , , , x1, y1, x2, y2, 0) + r.v := Vline(APPWIN, x1, y1, x2, y2) + VInsert(ROOT, r.v, x1, y1) + VRemove(ROOT, r.v, 1) + update_line_bb(r) + return r +end + +########################################################################## +# update_line_bb() updates various attributes of the line that +# change when the button is resized, etc. +########################################################################## +procedure update_line_bb(object) + if object.x1 < 0 then { + object.x2 -:= object.x1 + object.x1 := 0 + } + if object.x2 < 0 then { + object.x1 -:= object.x2 + object.x2 := 0 + } + if object.y1 < CANVASY then { + object.y2 -:= (object.y1 - CANVASY) + object.y1 := CANVASY + } + if object.y2 < CANVASY then { + object.y1 -:= (object.y2 - CANVASY) + object.y2 := CANVASY + } + object.x := minimum(object.x1, object.x2) - 2 + object.y := minimum(object.y1, object.y2) - 2 + object.w := abs(object.x1 - object.x2) + 4 + object.h := abs(object.y1 - object.y2) + 4 +end + +########################################################################## +# draw_line() draws the given line object. +########################################################################## +procedure draw_line(r) + r.v.ax1 := r.x1 + r.v.ay1 := r.y1 + r.v.ax2 := r.x2 + r.v.ay2 := r.y2 + VDraw(r.v) + return r +end + +########################################################################## +# outline_line() draws an outline for the given line. Outlines are +# used when the object is moved or resized. +########################################################################## +procedure outline_line(r) + DrawLine(XORWIN, r.x1, r.y1, r.x2, r.y2) +end + +########################################################################## +# drag_line() is a special procedure for dragging line objects. +########################################################################## +procedure drag_line(r) + local xoff, yoff, x1, y1, dx, dy + + x1 := r.x1 + y1 := r.y1 + dx := r.x2 - x1 + dy := r.y2 - y1 + xoff := x1 - &x + yoff := y1 - &y + DrawLine(XORWIN, x1, y1, x1 + dx, y1 + dy) + until Event(XORWIN) === (&lrelease | &mrelease | &rrelease) do { + DrawLine(XORWIN, x1, y1, x1 + dx, y1 + dy) + x1 := &x + xoff + y1 := &y + yoff + DrawLine(XORWIN, x1, y1, x1 + dx, y1 + dy) + } + DrawLine(XORWIN, x1, y1, x1 + dx, y1 + dy) + &x := r.x + x1 - r.x1 + &y := r.y + y1 - r.y1 +end + +########################################################################## +# load_line() restores a line object from session code. +########################################################################## +procedure load_line(r, o) + r.x1 := o.x + r.y1 := o.y + CANVASY + r.x2 := o.w + r.y2 := o.h + CANVASY + r.v := Vline(APPWIN, r.x1, r.y1, r.x2, r.y2) + VInsert(ROOT, r.v, r.x1, r.y1) + VRemove(ROOT, r.v, 1) +end + +########################################################################## +# save_line() augments the record for saving a line object. +########################################################################## +procedure save_line(r, o) + r.typ := "Line" + r.x := o.x1 + r.y := o.y1 - CANVASY + r.w := o.x2 + r.h := o.y2 - CANVASY + r.proc := &null + return +end + +########################################################################## +# display_line_atts() displays the attribute sheet with the current +# attributes for the given line instance. +########################################################################## +procedure display_line_atts(object) + local t, dx, dy + + t := table() + t["a_id"] := object.id + t["c_x1"] := object.x1 + t["d_y1"] := object.y1 - CANVASY + t["e_x2"] := object.x2 + t["f_y2"] := object.y2 - CANVASY + + repeat { + if line_dialog(t) == "Cancel" then + fail + + if illegal(t["a_id"], "ID", "s") | + illegal(t["c_x1"], "X1", "i") | + illegal(t["d_y1"], "Y1", "i") | + illegal(t["e_x2"], "X2", "i") | + illegal(t["f_y2"], "Y2", "i") + then + next + + unfocus_object(object) + erase_object(object) + + object.id := t["a_id"] + object.x1 := t["c_x1"] + object.y1 := t["d_y1"] + CANVASY + object.x2 := t["e_x2"] + object.y2 := t["f_y2"] + CANVASY + + # can't just do a move_object() here: doesn't work for line changes + update_line_bb(object) + draw_canvas() + focus_object(object) + DIRTY := 1 + break + } +end + +#===<<vib:begin>>=== modify using vib; do not remove this marker line +procedure line_dialog(win, deftbl) +static dstate +initial dstate := dsetup(win, + ["line_dialog:Sizer::1:0,0,350,138:",], + ["_cancel:Button:regular::192,87,50,30:Cancel",], + ["_okay:Button:regular:-1:127,86,50,30:Okay",], + ["a_id:Text::40:13,14,318,19:ID: \\=",], + ["c_x1:Text::3:13,42,59,19:x1: \\=",], + ["d_y1:Text::3:81,42,59,19:y1: \\=",], + ["e_x2:Text::3:204,42,59,19:x2: \\=",], + ["f_y2:Text::3:272,42,59,19:y2: \\=",], + ) +return dpopup(win, deftbl, dstate) +end +#===<<vib:end>>=== end of section maintained by vib diff --git a/ipl/gpacks/vib/viblist.icn b/ipl/gpacks/vib/viblist.icn new file mode 100644 index 0000000..66fc813 --- /dev/null +++ b/ipl/gpacks/vib/viblist.icn @@ -0,0 +1,168 @@ +############################################################################ +# +# viblist.icn -- procedures for defining a list object +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$include "vdefns.icn" +$include "vibdefn.icn" + +$define MINIMUM_HEIGHT (VSlider_DefWidth * VSlider_MinAspect) +$define MINIMUM_WIDTH (VFWidth + VSlider_DefWidth + 10) +$define DEFAULT_HEIGHT 100 +$define DEFAULT_WIDTH 100 +$define DEFAULT_STYLE "w" +$define DEFAULT_SCROLL 0 + +########################################################################## +# list_obj: +# v : vidget used for drawing list object +# proc : name of user callback procedure +# id : unique means of identifying instance +# x,y,w,h : bounding box +# style : "r", "w", or "a" indicating list editing mode +# scroll : 1 for passive scrolling that waits for mouse release +########################################################################## +record list_obj(v, proc, id, x, y, w, h, style, scroll, focus) + +########################################################################## +# create_list() creates a list instance and draws it. +########################################################################## +procedure create_list(x, y, w, h, style, scroll) + local r, id + + /w := DEFAULT_WIDTH + /h := DEFAULT_HEIGHT + /style := DEFAULT_STYLE + /scroll := DEFAULT_SCROLL + id := next_id("list") + r := list_obj(, "list_cb" || id, "list" || id, x, y, w, h, style, scroll) + r.v := Vlist(ROOT, x, y, APPWIN, , id, [], scroll, w, h, style) + VRemove(ROOT, r.v, 1) + return r +end + +########################################################################## +# draw_list() draws the given list object. +########################################################################## +procedure draw_list(r) + VResize(r.v) + VDraw(r.v) + return r +end + +########################################################################## +# update_list_bb() enforces a minimum size when resizing. +########################################################################## +procedure update_list_bb(object) + object.w <:= MINIMUM_WIDTH + object.h <:= MINIMUM_HEIGHT +end + +########################################################################## +# load_list() restores a list object from session code. +########################################################################## +procedure load_list(r, o) + r.style := o.sty + if integer(o.num) > 0 then + r.scroll := 1 + else + r.scroll := &null + r.v := Vlist(ROOT, r.x, r.y, + APPWIN, , r.id, [], r.scroll, r.w, r.h, r.style) + VRemove(ROOT, r.v, 1) +end + +########################################################################## +# save_list_obj() augments the record for saving a list object. +# (_obj is in the name due to a name conflict with a library procedure.) +########################################################################## +procedure save_list_obj(r, o) + r.typ := "List" + r.sty := o.style + r.num := o.scroll + return +end + +########################################################################## +# display_list_atts() displays the attribute sheet with the current +# attributes for the given list instance. +########################################################################## +procedure display_list_atts(object) + local t + + t := table() + t["a_id"] := object.id + t["b_callback"] := object.proc + t["c_x"] := object.x + t["d_y"] := object.y - CANVASY + t["e_width"] := object.w + t["f_height"] := object.h + + t["g_style"] := case object.style of { + "r" : "read only" + "w" : "select one" + "a" : "select many" + } + + repeat { + if list_dialog(t) == "Cancel" then + fail + + if illegal(t["a_id"], "ID", "s") | + illegal(t["b_callback"], "Callback", "p") | + illegal(t["c_x"], "X", "i") | + illegal(t["d_y"], "Y", "i") | + illegal(t["e_width"], "Width", MINIMUM_WIDTH) | + illegal(t["f_height"], "Height", MINIMUM_HEIGHT) + then + next + + object.id := t["a_id"] + object.proc := t["b_callback"] + + object.style := case t["g_style"] of { + "read only" : "r" + "select one" : "w" + "select many" : "a" + } + + unfocus_object(object) + move_object(object, + t["c_x"], t["d_y"] + CANVASY, t["e_width"], t["f_height"]) + + # delete and recreate the vidget in case the style changed + erase_object(object) + object.v := Vlist(ROOT, object.x, object.y, APPWIN, , object.id, + [], object.scroll, object.w, object.h, object.style) + VRemove(ROOT, object.v) + + draw_object(object) + focus_object(object) + break + } +end + +#===<<vib:begin>>=== modify using vib; do not remove this marker line +procedure list_dialog(win, deftbl) +static dstate +initial dstate := dsetup(win, + ["list_dialog:Sizer::1:0,0,383,198:",], + ["_cancel:Button:regular::197,148,50,30:Cancel",], + ["_okay:Button:regular:-1:130,148,50,30:Okay",], + ["a_id:Text::40:13,14,360,19:ID: \\=",], + ["b_callback:Text::40:13,35,360,19:callback: \\=",], + ["c_x:Text::3:13,62,101,19: x: \\=",], + ["d_y:Text::3:13,83,101,19: y: \\=",], + ["e_width:Text::3:129,63,101,19: width: \\=",], + ["f_height:Text::3:129,84,101,19: height: \\=",], + ["g_style:Choice::3:266,59,106,63:",, + ["read only","select one","select many"]], + ) +return dpopup(win, deftbl, dstate) +end +#===<<vib:end>>=== end of section maintained by vib diff --git a/ipl/gpacks/vib/vibmenu.icn b/ipl/gpacks/vib/vibmenu.icn new file mode 100644 index 0000000..d9d4c1e --- /dev/null +++ b/ipl/gpacks/vib/vibmenu.icn @@ -0,0 +1,468 @@ +############################################################################ +# +# vibmenu.icn -- procedures for defining a menu object +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$include "vdefns.icn" +$include "vibdefn.icn" + +global startyMENU, MENU_TALK +global MENU_VIDGET +global reg_list, ins_list +global SIM_TAB + +########################################################################## +# menu_obj: +# v : vidget used for drawing menu +# proc : name of user callback procedure +# id : unique means of identifying instance +# x,y,w,h : bounding box +# label : menu button label +# lx,ly : label coordinates +# style : style of menu ... currently only pull down is supported +# focus : should focus lines be drawn around this object? +# items : a list of menu items that make up the menu +# +# menu_item: +# label : menu choice name +# items : a list of menu_items for a submenu, or an empty list +# +# menu_id: +# v : text vidget for label field +# item : corresponding menu_item record +########################################################################## + +record menu_obj(v, proc, id, x, y, w, h, label, lx, ly, style, focus, items) +record menu_item(label, items) +record menu_id(tv, item) + +########################################################################## +# create_menu() creates a menu instance and draws the menu button. +########################################################################## +procedure create_menu(x, y, label, style) + local r, id + + id := next_id("menu") + /style := "pull" + r := menu_obj(, "menu_cb" || id, "menu" || id, + x, y, 0, 0, label, 0, 0, style, 0, []) + r.v := Vbutton(ROOT, x, y, APPWIN, label, , id, V_RECT) + VRemove(ROOT, r.v, 1) + return r +end + +########################################################################## +# copy_submenu() recursively copies a cascading menu. +########################################################################## +procedure copy_submenu(old, temp) + local i + + /temp := copy(old) + if *old.items > 0 then { + temp.items := [] + every put(temp.items, copy_submenu(!old.items)) + } + return temp +end + +########################################################################## +# copy_menu() makes a copy of a menu old and returns it in new. +########################################################################## +procedure copy_menu(new, old) + every put(new.items, copy_submenu(!old.items)) +end + +########################################################################## +# add_item() adds a menu choice with name "label" to the menu at the +# location indicated by "after". +########################################################################## +procedure add_item(menu, label, after) + local choice + + after >:= *menu.items + choice := menu_item(label, []) + menu.items := menu.items[1:after+1] ||| [choice] ||| menu.items[after+1:0] +end + +########################################################################## +# update_menu_bb() updates various attributes of the menu that +# change when the menu button label is altered. +########################################################################## +procedure update_menu_bb(object) + object.w := object.v.aw # disallow changes + object.h := object.v.ah + # .lx/.ly values must agree with locations drawn by menu vidgets + # else the simulation of a menu leaves the label in the wrong place + # and moving the menu then leaves debris behind on the screen + object.lx := object.x + 4 + object.ly := object.y + WAttrib(APPWIN, "ascent") + 4 +end + +########################################################################## +# draw_menu() draws the given menu button object. +########################################################################## +procedure draw_menu(r) + VResize(r.v, r.x, r.y, r.w, r.h) + VDraw(r.v) + return r +end + +########################################################################## +# load_menu() restores a menu object from session code. +########################################################################## +procedure load_menu(r, o) + r.style := o.sty + r.label := o.lbl + r.items := load_submenu(o.etc) + r.v := Vbutton(ROOT, r.x, r.y, APPWIN, r.label, , r.id, V_RECT) + VRemove(ROOT, r.v, 1) +end + +########################################################################## +# load_submenu() restores a menu or submenu list. +########################################################################## +procedure load_submenu(spec) + local i, r, lst + + lst := [] + while i := get(spec) do { + r := menu_item() + r.label := i + if type(spec[1]) == "list" then { + r.items := load_submenu(get(spec)) + } + else + r.items := [] + put(lst, r) + } + return lst +end + +########################################################################## +# save_menu() augments the record for saving a menu object. +########################################################################## +procedure save_menu(r, o) + r.typ := "Menu" + r.lbl := o.label + r.sty := o.style + r.etc := save_submenu(o.items) + return +end + +########################################################################## +# save_submenu() builds a list representing a submenu. +########################################################################## +procedure save_submenu(items) + local l, i + l := [] + every i := !items do { + put(l, i.label) + if *i.items > 0 then + put(l, save_submenu(i.items)) + } + return l +end + +########################################################################## +# simulate_sub_menu() is called by simulate_menu to recursively construct +# WIT submenus and place them in a table for reference +# by simulate_menu(). +########################################################################## +procedure simulate_sub_menu(obj, label) + local i, temp_list + + every i := 1 to *obj.items do { + if *obj.items[i].items > 0 then + simulate_sub_menu(obj.items[i], label || "_" || obj.items[i].label) + } + temp_list := [&window] + every i := 1 to *obj.items do { + put(temp_list, obj.items[i].label) + if *obj.items[i].items > 0 then + put(temp_list, SIM_TAB["id_" || label || "_" || obj.items[i].label]) + else + put(temp_list, &null) # null callback + } + SIM_TAB["id_" || label] := Vsub_menu ! temp_list +end + +########################################################################## +# simulate_menu() creates a complete WIT menu object so that the +# VIB user can see what the menu looks like without +# prototyping. +########################################################################## +procedure simulate_menu(obj) + local i, temp_list, sim_menu, tmp + + SIM_TAB := table() + every i := 1 to *obj.items do { + if *obj.items[i].items > 0 then + simulate_sub_menu(obj.items[i], obj.items[i].label) + } + temp_list := [&window] + every i := 1 to *obj.items do { + put(temp_list, obj.items[i].label) + if *obj.items[i].items > 0 then + put(temp_list, SIM_TAB["id_" || obj.items[i].label]) + else + put(temp_list, &null) # null callback + } + sim_menu := Vmenu_bar_item(&window, obj.label, , , , , Vsub_menu ! temp_list) + tmp := ScratchCanvas(ROOT.win, obj.w, obj.h) + CopyArea(ROOT.win, tmp, obj.x, obj.y, obj.w, obj.h) + VInsert(ROOT, sim_menu, obj.x, obj.y) + VResize(sim_menu) + VEvent(sim_menu, &mpress) + VRemove(ROOT, sim_menu, 1) + CopyArea(tmp, ROOT.win, 0, 0, obj.w, obj.h, obj.x, obj.y) + EraseArea(tmp) +end + +########################################################################## +# menu_atts() defines the attribute sheet template for a menu object. +########################################################################## +procedure menu_atts() + local tempy + + MENU_TALK := Vdialog(&window, PAD, PAD) + tempy := 0 + VRegister(MENU_TALK, + Vtext(&window, "menu label: ", , 1, TEXTCHARS, LBMASK), 0, tempy) + tempy +:= PAD + VRegister(MENU_TALK, + Vtext(&window, "ID: ", , 2, TEXTCHARS, IDMASK), 0, tempy) + tempy +:= PAD + VRegister(MENU_TALK, + Vtext(&window, "callback: ", , 3, TEXTCHARS, CBMASK), 0, tempy) + + VRegister(MENU_TALK, + Vtext(&window, "x: ", , 4, 3, &digits), 80 + TEXTWIDTH + 10, 0) + VRegister(MENU_TALK, + Vtext(&window, "y: ", , 5, 3, &digits), 80 + TEXTWIDTH + 10, PAD) + VFormat(MENU_TALK) + startyMENU := tempy +end + +########################################################################## +# display_menu_atts() displays the attribute sheet with the current +# attributes for the given menu instance. +########################################################################## +procedure display_menu_atts(object) + local i, data, send_data, new, v, dw, l + initial menu_atts() + + new := copy(object) + new.y -:= CANVASY + new.items := [] + copy_menu(new, object) + + repeat { + + menu_list_atts(MENU_TALK, startyMENU, new.items) + VFormat(MENU_TALK) + + MENU_VIDGET := &null + send_data := [new.label, new.id, new.proc, new.x, new.y] + every put(send_data, (!new.items).label) + data := VOpenDialog(MENU_TALK, , "menu_dialog", send_data, "Okay") + every VUnregister(MENU_TALK, !reg_list) + every VRemove(MENU_TALK, !ins_list, 1) + + if data === send_data then + fail # cancelled + + new.label := strip(get(data)) + new.id := strip(get(data)) + new.proc := strip(get(data)) + new.x := get(data) + new.y := get(data) + every (!new.items).label := get(data) + + # if "add" or "del" was pressed, process it and loop to re-post dialog + if \MENU_VIDGET then { + l := [] + every i := 1 to *new.items do { + v := reg_list[i] + if v.ay - PAD < MENU_VIDGET.ay-1 < v.ay then + put(l, menu_item("", [])) + if v.ay ~= MENU_VIDGET.ay-1 then + put(l, new.items[i]) + } + if MENU_VIDGET.ay-1 > reg_list[*new.items].ay | *l = 0 then + put(l, menu_item("", [])) + new.items := l + next + } + + # check for legal field values + + if illegal(new.id, "ID", "s") | + illegal(new.label, "Label", "l") | + illegal(new.proc, "Callback", "p") | + illegal(new.x, "X", "i") | + illegal(new.y, "Y", "i") + then + fail + + # everything is valid + + dw := VFWidth * (*new.label - *object.label) + + object.label := new.label + object.id := new.id + object.proc := new.proc + object.items := new.items + + object.v.s := object.label + object.v.aw := object.w + dw + + unfocus_object(object) + move_object(object, new.x, new.y + CANVASY, object.w, object.h) + focus_object(object) + break + } +end + +########################################################################## +# display_submenu_atts() displays the attribute sheet with the current +# attributes for the given submenu instance. +########################################################################## +procedure display_submenu_atts(button, val) + local submenu_talk, send_data, data, old_reg, old_ins + local entry, items, s, i, v + + old_reg := reg_list + old_ins := ins_list + entry := button.id.item + items := copy(entry.items) + if *items = 0 then + every 1 to 3 do + put(items, menu_item("", [])) + + repeat { + + submenu_talk := Vdialog(&window, PAD, PAD) + v := Vmessage(&window, "\"" || button.id.tv.data || \"\" submenu entries") + VInsert(submenu_talk, v, 0, 0) + menu_list_atts(submenu_talk, 0, items) + VFormat(submenu_talk) + + MENU_VIDGET := &null + send_data := [] + every put(send_data, (!items).label) + data := VOpenDialog(submenu_talk, , "submenu_dialog", send_data, "Okay") + every VUnregister(MENU_TALK, !reg_list) + every VRemove(MENU_TALK, !ins_list, 1) + + if data === send_data then { + reg_list := old_reg + ins_list := old_ins + fail # cancelled + } + + every (!items).label := get(data) # update new labels + + if *(items := update_menu_list(items)) > 0 then + next # loop to re-post dialog + + # the revised list has been accepted + + entry.items := items + VErase(button) + if *items = 0 then + s := "create submenu" + else + s := "edit submenu (" || *items || ")" + button.aw +:= VFWidth * (*s - *button.s) + button.s := s + VResize(button) + VDraw(button) + break + } + reg_list := old_reg + ins_list := old_ins +end + +########################################################################## +# menu_list_atts() adds the menu items (with add/del/submenu buttons) +# and okay/cancel buttons to a dialog box. +# ins_list and reg_list are set. +########################################################################## +procedure menu_list_atts(menu, y, itemlist) + local i, s, v, id + + # construct text fields with "add", "del", and "submenu" buttons + + reg_list := [] + ins_list := [] + every i := 0 to *itemlist do { + y +:= PAD + + v := Vbutton(&window, "add", menu_mod_cb, V_OK, , 28, 17) + VInsert(menu, v, 0, y + PAD / 2) + put(ins_list, v) + + if i = 0 then + next + + v := Vbutton(&window, "del", menu_mod_cb, V_OK, , 28, 17) + VInsert(menu, v, 35 + TEXTWIDTH, y + 1) + put(ins_list, v) + + v := Vtext(&window, "", , 100 + i, TEXTCHARS, LBMASK) + VRegister(menu, v, 35, y) + put(reg_list, v) + id := menu_id(v, itemlist[i]) + + if *itemlist[i].items = 0 then + s := "create submenu" + else + s := "edit submenu (" || *itemlist[i].items || ")" + v := Vbutton(&window, s, display_submenu_atts, id, , , 17) + VInsert(menu, v, 35 + TEXTWIDTH + 40, y + 1) + put(ins_list, v) + } + + # add "Okay" and "Cancel" + y +:= 2 * PAD + v := Vbutton(&window, "Okay", , V_OK, , 50, 30) + VInsert(menu, v, TEXTWIDTH / 2 + 30, y) + put(ins_list, v) + v := Vbutton(&window, "Cancel", , V_CANCEL, , 50, 30) + VInsert(menu, v, TEXTWIDTH / 2 + 100, y) + put(ins_list, v) +end + +########################################################################## +# update_menu_list() creates a new item list reflecting adds and deletes. +########################################################################## +procedure update_menu_list(oldlist) + local newlist, v, i + + if /MENU_VIDGET then + fail + newlist := [] + every i := 1 to *oldlist do { + v := reg_list[i] + if v.ay - PAD < MENU_VIDGET.ay-1 < v.ay then + put(newlist, menu_item("", [])) + if v.ay ~= MENU_VIDGET.ay-1 then + put(newlist, oldlist[i]) + } + if MENU_VIDGET.ay-1 > reg_list[*oldlist].ay then + put(newlist, menu_item("", [])) + MENU_VIDGET := &null + return newlist +end + +########################################################################## +# menu_mod_cb is called when an "add" or "del" button is pressed. +########################################################################## +procedure menu_mod_cb(v) + MENU_VIDGET := v +end diff --git a/ipl/gpacks/vib/vibradio.icn b/ipl/gpacks/vib/vibradio.icn new file mode 100644 index 0000000..b164594 --- /dev/null +++ b/ipl/gpacks/vib/vibradio.icn @@ -0,0 +1,209 @@ +############################################################################ +# +# vibradio.icn -- procedures for defining a radio button object +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$include "vibdefn.icn" + +global RB_starty, RADIO_TALK, RADIO_VIDGET + +########################################################################## +# radio_button_obj: +# v : vidget used for drawing radio button +# proc : name of user callback procedure +# id : unique means of identifying instance +# x,y,w,h : bounding box +# focus : should focus lines be drawn around this object? +# alts : a list of button labels making up the radio button object +########################################################################## +record radio_button_obj(v, proc, id, x, y, w, h, focus, alts) + +########################################################################## +# create_radio_button() creates a radio button instance and draws the +# button if it is a first class object. +########################################################################## +procedure create_radio_button(x, y, alts) + local r, id + + id := next_id("radio_button") + r := radio_button_obj(, "radio_button_cb" || id, "radio_button" || id, + x, y, 0, 0, 0, alts) + r.v := Vradio_buttons(ROOT, x, y, APPWIN, alts, , id, V_DIAMOND_NO) + r.w := r.v.aw + r.h := r.v.ah + VRemove(ROOT, r.v, 1) + return r +end + +########################################################################## +# update_radio_bb() disallows resizing of a radio button object. +########################################################################## +procedure update_radio_bb(object) + object.w := object.v.aw + object.h := object.v.ah +end + +########################################################################## +# draw_radio_button() draws the given radio button object. +########################################################################## +procedure draw_radio_button(r) + VDraw(r.v) + return r +end + +########################################################################## +# load_radio_button() restores a radio button object from session code. +########################################################################## +procedure load_radio_button(r, o) + r.alts := o.etc + r.v := Vradio_buttons(ROOT, r.x, r.y, APPWIN, r.alts, , r.id, V_DIAMOND_NO) + r.w := r.v.aw + r.h := r.v.ah + VRemove(ROOT, r.v, 1) +end + +########################################################################## +# save_radio_button() augments the record for saving a radio_button object. +########################################################################## +procedure save_radio_button(r, o) + r.typ := "Choice" + r.num := *o.alts + r.etc := copy(o.alts) + return +end + +########################################################################## +# radio_button_atts() defines the attribute sheet template for a radio +# button object. +########################################################################## +procedure radio_button_atts() + local tempy + + RADIO_TALK := Vdialog(&window, PAD, PAD) + tempy := 0 + VRegister(RADIO_TALK, + Vtext(&window, "ID: ",, 1, TEXTCHARS, IDMASK), 0, tempy) + tempy +:= PAD + VRegister(RADIO_TALK, + Vtext(&window, "callback: ",, 3, TEXTCHARS, CBMASK), 0, tempy) + tempy +:= (3 * PAD)/2 + VRegister(RADIO_TALK, Vtext(&window, " x: ",, 4, 3, &digits), 0, tempy) + tempy +:= PAD + VRegister(RADIO_TALK, Vtext(&window, " y: ",, 5, 3, &digits), 0, tempy) + VFormat(RADIO_TALK) + RB_starty := tempy +end + +########################################################################## +# display_radio_button_atts() displays the attribute sheet with the current +# attributes for the given radio button instance. +########################################################################## +procedure display_radio_button_atts(object) + local tempy, i, send_data, data, new, v, ok, nok, reg_list, ins_list, l + initial radio_button_atts() + + new := copy(object) + new.y -:= CANVASY + new.alts := copy(object.alts) + + repeat { + reg_list := [] + ins_list := [] + tempy := RB_starty + + # construct text fields and "add" and "del" buttons + every i := 0 to *new.alts do { + tempy +:= PAD + v := Vbutton(&window, "add", radio_cb, V_OK, , 28, 17) + VInsert(RADIO_TALK, v, 0, tempy + PAD / 2) + put(ins_list, v) + if i = 0 then + next + v := Vbutton(&window, "del", radio_cb, V_OK, , 28, 17) + VInsert(RADIO_TALK, v, 35 + TEXTWIDTH, tempy + 1) + put(ins_list, v) + v := Vtext(&window, "", , 5 + i, TEXTCHARS, LBMASK) + VRegister(RADIO_TALK, v, 35, tempy) + put(reg_list, v) + } + + # add "Okay" and "Cancel" + tempy +:= 2 * PAD + ok := Vbutton(&window, "Okay", , V_OK, , 50, 30) + nok := Vbutton(&window, "Cancel", , V_CANCEL, , 50, 30) + VInsert(RADIO_TALK, ok, TEXTWIDTH / 2 - 30, tempy) + VInsert(RADIO_TALK, nok, TEXTWIDTH / 2 + 40, tempy) + put(ins_list, ok, nok) + + # post the dialog + RADIO_VIDGET := &null + VFormat(RADIO_TALK) + send_data := [new.id, new.proc, new.x, new.y] ||| new.alts + data := VOpenDialog(RADIO_TALK, , "radio_dialog", send_data, "Okay") + every VUnregister(RADIO_TALK, !reg_list) + every VRemove(RADIO_TALK, !ins_list, 1) + + if data === send_data then + fail # cancelled + + # save new values + new.id := strip(get(data)) + new.proc := strip(get(data)) + new.x := get(data) + new.y := get(data) + every !new.alts := get(data) + + # if "add" or "del" was pressed, process it and loop to re-post dialog + if \RADIO_VIDGET then { + l := [] + every v := reg_list[1 to *new.alts] do { + if v.ay - PAD < RADIO_VIDGET.ay-1 < v.ay then + put(l, "") + if v.ay ~= RADIO_VIDGET.ay-1 then + put(l, v.data) + } + if RADIO_VIDGET.ay-1 > reg_list[*new.alts].ay | *l = 0 then + put(l, "") + new.alts := l + next + } + + # check for legal field values + if illegal(new.id, "ID", "s") | + illegal(new.proc, "Callback", "p") | + illegal(new.x, "X", "i") | + illegal(new.y, "Y", "i") + then + next + + # everything is valid + object.proc := new.proc + object.id := new.id + object.alts := new.alts + + unfocus_object(object) + EraseArea(object.x, object.y, object.w, object.h) + + object.v := Vradio_buttons(ROOT, + object.x, object.y, APPWIN, new.alts, , object.v.id, V_DIAMOND_NO) + object.w := object.v.aw + object.h := object.v.ah + VRemove(ROOT, object.v, 1) + + move_object(object, new.x, new.y + CANVASY, object.w, object.h) + focus_object(object) + break + } +end + +########################################################################## +# radio_cb is called when an "add" or "del" button is pressed. +########################################################################## +procedure radio_cb(v) + RADIO_VIDGET := v +end diff --git a/ipl/gpacks/vib/vibrect.icn b/ipl/gpacks/vib/vibrect.icn new file mode 100644 index 0000000..5d98757 --- /dev/null +++ b/ipl/gpacks/vib/vibrect.icn @@ -0,0 +1,135 @@ +############################################################################ +# +# vibrect.icn -- procedures for defining an area object +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$include "vibdefn.icn" + +########################################################################## +# rect_obj: +# v : vidget used for drawing rectangle +# proc : name of user callback procedure +# id : unique means of identifying a rectangle instance +# x,y,w,h : bounding box +# style : invisible, sunken, grooved, raised +# focus : should focus lines be drawn around this object? +########################################################################## +record rect_obj(v, proc, id, x, y, w, h, style, focus) + +########################################################################## +# create_rect() creates a rect instance and draws the rect if +# it is a first class object. +########################################################################## +procedure create_rect(x, y, w, h, style) + local r, id + + id := next_id("region") + r := rect_obj(, "region_cb" || id, "region" || id, x, y, w, h, style, 0) + r.v := Vpane(ROOT, x, y, APPWIN, , id, style, w, h) + VRemove(ROOT, r.v, 1) + return r +end + +########################################################################## +# draw_rect() draws the given rect instance. +########################################################################## +procedure draw_rect(r) + if r.style == "invisible" then { + WAttrib(APPWIN, "linestyle=dashed") + DrawRectangle(APPWIN, r.x, r.y, r.w - 1, r.h - 1) + WAttrib(APPWIN, "linestyle=solid") + } + else + VDraw(r.v) + return r +end + +########################################################################## +# load_rect() restores a rect object from session code. +########################################################################## +procedure load_rect(r, o) + if o.sty ~== "" then + r.style := o.sty + else if integer(o.num) > 0 then + r.style := "grooved" + else + r.style := "invisible" + r.v := Vpane(ROOT, r.x, r.y, APPWIN, , r.id, r.style, r.w, r.h) + VRemove(ROOT, r.v, 1) +end + +########################################################################## +# save_rect() augments the record for saving a rect object. +########################################################################## +procedure save_rect(r, o) + r.typ := "Rect" + r.sty := o.style + return +end + +########################################################################## +# display_rect_atts() displays the attribute sheet with the current +# attributes for the given rect instance. +########################################################################## +procedure display_rect_atts(object) + local t + + t := table() + t["_style"] := object.style + t["a_id"] := object.id + t["b_callback"] := object.proc + t["c_x"] := object.x + t["d_y"] := object.y - CANVASY + t["e_width"] := object.w + t["f_height"] := object.h + + repeat { + if rect_dialog(t) == "Cancel" then + fail + + if illegal(t["a_id"], "ID", "s") | + illegal(t["b_callback"], "Callback", "p") | + illegal(t["c_x"], "X", "i") | + illegal(t["d_y"], "Y", "i") | + illegal(t["e_width"], "Width", MIN_W) | + illegal(t["f_height"], "Height", MIN_H) + then + next + + object.v.style := object.style := t["_style"] + object.id := t["a_id"] + object.proc := t["b_callback"] + unfocus_object(object) + move_object(object, + t["c_x"], t["d_y"] + CANVASY, t["e_width"], t["f_height"]) + focus_object(object) + break + } +end + + + +#===<<vib:begin>>=== modify using vib; do not remove this marker line +procedure rect_dialog(win, deftbl) +static dstate +initial dstate := dsetup(win, + ["rect_dialog:Sizer::1:0,0,388,216:",], + ["_cancel:Button:regular::216,167,50,30:Cancel",], + ["_okay:Button:regular:-1:146,167,50,30:Okay",], + ["_style:Choice::4:281,62,92,84:",, + ["invisible","sunken","grooved","raised"]], + ["a_id:Text::40:13,14,360,19:ID: \\=",], + ["b_callback:Text::40:13,35,360,19:callback: \\=",], + ["c_x:Text::3:13,62,101,19: x: \\=",], + ["d_y:Text::3:13,88,101,19: y: \\=",], + ["e_width:Text::3:132,62,101,19: width: \\=",], + ["f_height:Text::3:132,88,101,19: height: \\=",], + ) +return dpopup(win, deftbl, dstate) +end +#===<<vib:end>>=== end of section maintained by vib diff --git a/ipl/gpacks/vib/vibsizer.icn b/ipl/gpacks/vib/vibsizer.icn new file mode 100644 index 0000000..dcee0ac --- /dev/null +++ b/ipl/gpacks/vib/vibsizer.icn @@ -0,0 +1,197 @@ +############################################################################ +# +# vibsizer.icn -- procedures for defining a sizer object +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$include "vibdefn.icn" + +########################################################################## +# sizer_obj: +# x,y,w,h : bounding box +# label : window label +# id : procedure id (only significant when used as dialog) +# dlog : is this a dialog box instead of a main window? +# proc : name of user callback procedure (unused) +# focus : should focus lines be drawn around this object? (not used) +# compose : is the object part of another? (not used) +########################################################################## +record sizer_obj(x, y, w, h, label, id, dlog, proc, focus, compose) + +########################################################################## +# create_sizer() creates a sizer instance. +########################################################################## +procedure create_sizer() + local x, y, r + + x := 600 - SZDIM + y := 400 - SZDIM + 65 + x >:= WAttrib("width") - SZDIM - 10 + y >:= WAttrib("height") - SZDIM - 10 + r := sizer_obj(x, y, SZDIM, SZDIM, "") + return r +end + +########################################################################## +# move_sizer() erases the sizer, updates its location, and redraws. +########################################################################## +procedure move_sizer(r, newx, newy) + erase_sizer(r) + newx <:= 0 + newx >:= WAttrib("width") - 11 + newy <:= CANVASY + newy >:= WAttrib("height") - 11 + r.x := newx + r.y := newy + draw_sizer(r) + DIRTY := 1 +end + +############################################################################ +# drag_sizer() resizes the application window by dragging the sizer. +############################################################################ +procedure drag_sizer() + local x, y + + unfocus_object(\FOCUS) + x := &x + y := &y + DrawRectangle(XORWIN, 0, CANVASY, x, y - CANVASY) + repeat case Event() of { + &ldrag: { + DrawRectangle(XORWIN, 0, CANVASY, x, y - CANVASY) + x := &x + y := &y + x <:= SZDIM + y <:= SZDIM + DrawRectangle(XORWIN, 0, CANVASY, x, y - CANVASY) + } + &lrelease: { + DrawRectangle(XORWIN, 0, CANVASY, x, y - CANVASY) + move_sizer(SIZER, x - SZDIM, y - SZDIM) + draw_canvas() + return + } + } +end + +########################################################################## +# draw_sizer() draws the given sizer object. +########################################################################## +procedure draw_sizer(r) + DrawLine(APPWIN, 0, r.y+SZDIM, r.x+SZDIM, r.y+SZDIM, r.x+SZDIM, CANVASY) + BevelRectangle(APPWIN, r.x, r.y, SZDIM, SZDIM, -2) + return r +end + +########################################################################## +# erase_sizer() erases the given sizer object. +########################################################################## +procedure erase_sizer(r) + EraseArea(APPWIN, r.x, r.y, SZDIM + 1, SZDIM + 1, + 0, r.y + SZDIM, r.x, 1, r.x + SZDIM, CANVASY, 1, r.y) + return r +end + +########################################################################## +# load_sizer() restores the sizer object from session code. +########################################################################## +procedure load_sizer(r, o) + local winw, winh + + winw := WAttrib("width") + winh := WAttrib("height") + pop(O_LIST) # remove sizer from object list + r.label := o.lbl + r.x := r.x + r.w - SZDIM + r.y := r.y + r.h - SZDIM + r.w := r.h := SZDIM + r.dlog := ("" ~== o.num) + erase_sizer(SIZER) + if (r.x + r.w + 11 > winw) | (r.y + r.h + 11 > winh) then { + winw <:= r.x + r.w + 11 + winh <:= r.y + r.h + 11 + WAttrib("width=" || (ROOT.aw := winw), "height=" || (ROOT.ah := winh)) + draw_decor() + } + SIZER := r +end + +########################################################################## +# save_sizer() augments the record for saving the sizer object. +########################################################################## +procedure save_sizer(r, o) + r.typ := "Sizer" + r.lbl := o.label + r.w := r.x + r.w + r.h := r.y + r.h + r.x := r.y := 0 + r.num := o.dlog + return +end + +########################################################################## +# display_sizer_atts() displays the attribute sheet with the current +# attributes for the given sizer instance. +# This amounts to the window dimensions ... +########################################################################## +procedure display_sizer_atts(object) + local t + + t := table() + t["a_name"] := object.id + t["b_label"] := object.label + t["c_width"] := object.x + object.w + t["d_height"] := object.y + object.h - CANVASY + t["_dialog"] := object.dlog + + repeat { + if sizer_dialog(t) == "Cancel" then + fail + + if illegal(t["a_name"], "Procedure name", "p") | + illegal(t["b_label"], "Label", "l") | + illegal(t["c_width"], "Width", SZDIM) | + illegal(t["d_height"], "Height", SZDIM) + then + next + + if t["c_width"] >= WAttrib("width") | + t["d_height"] >= WAttrib("height") then { + Notice("The VIB window is not large enough", + "to model a canvas of that size.") + next + } + + erase_sizer(object) + object.id := t["a_name"] + object.label := t["b_label"] + object.x := t["c_width"] - object.w + object.y := t["d_height"] - object.h + CANVASY + object.dlog := t["_dialog"] + draw_sizer(object) + DIRTY := 1 + break + } +end + +#===<<vib:begin>>=== modify using vib; do not remove this marker line +procedure sizer_dialog(win, deftbl) +static dstate +initial dstate := dsetup(win, + ["sizer_dialog:Sizer::1:0,0,500,180:",], + ["_cancel:Button:regular::265,125,50,30:Cancel",], + ["_dialog:Button:check:1:278,77,118,20:dialog window",], + ["_okay:Button:regular:-1:185,125,50,30:Okay",], + ["a_name:Text::40:13,14,402,19:procedure name: \\=",], + ["b_label:Text::50:13,35,472,19:window label: \\=",], + ["c_width:Text::3:13,60,143,19: width: \\=",], + ["d_height:Text::3:13,81,143,19: height: \\=",], + ) +return dpopup(win, deftbl, dstate) +end +#===<<vib:end>>=== end of section maintained by vib diff --git a/ipl/gpacks/vib/vibslidr.icn b/ipl/gpacks/vib/vibslidr.icn new file mode 100644 index 0000000..a7fca9e --- /dev/null +++ b/ipl/gpacks/vib/vibslidr.icn @@ -0,0 +1,207 @@ +############################################################################ +# +# vibslidr.icn -- procedures for defining slider and scrollbar objects +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$include "vibdefn.icn" +$include "vdefns.icn" + +########################################################################## +# slider_obj: +# v : vidget used for drawing +# proc : name of user callback procedure +# filter : filter out dragging events? +# id : unique identifier +# x,y,w,h : bounding box +# min : min value of range +# max : max value of range +# value : current value within range +# typ : "Slider" or "Scrollbar" +# focus : should focus lines be drawn around this object? +########################################################################## +record slider_obj(v, proc, filter, id, x, y, w, h, min, max, value, typ, focus) + +########################################################################## +# create_slider() creates a slider instance and draws the slider. +########################################################################## +procedure create_slider(x, y, w, h, typ, min, max, value, filter) + local r, id, prefix + + if typ == "Scrollbar" then + prefix := "sbar" + else + prefix := "slider" + id := next_id(prefix) + + r := slider_obj(, prefix || "_cb" || id, filter, prefix || id, + x, y, w, h, min, max, value, typ, 0) + + r.v := slider_vidget(id, typ, x, y, w, h) + VRemove(ROOT, r.v, 1) + return r +end + +########################################################################## +# slider_vidget() creates the appropriate vidget for a slider or scrollbar. +########################################################################## +procedure slider_vidget(id, typ, x, y, w, h) + local dir + + dir := if w > h then "h" else "v" + return case dir || typ of { + "vSlider": Vvert_slider(ROOT, x, y, APPWIN, , id, h, w, 1.0, 0.0) + "hSlider": Vhoriz_slider(ROOT, x, y, APPWIN, , id, w, h) + "vScrollbar": Vvert_scrollbar(ROOT, x, y, APPWIN, , id, h, w, 1.0, 0.0) + "hScrollbar": Vhoriz_scrollbar(ROOT, x, y, APPWIN, , id, w, h) + } +end + +########################################################################## +# update_slider_bb() updates attributes in response to resizing. +########################################################################## +procedure update_slider_bb(object) + if object.w > object.h then { + object.w <:= VSlider_MinAspect * VSlider_MinWidth + object.h >:= object.w / VSlider_MinAspect + } + else { + object.h <:= VSlider_MinAspect * VSlider_MinWidth + object.w >:= object.h / VSlider_MinAspect + } +end + +########################################################################## +# draw_slider() draws the given slider object. +########################################################################## +procedure draw_slider(r) + VSetState(r.v, abs((r.value - r.min) / (real(r.max - r.min)))) + VDraw(r.v) + return r +end + +########################################################################## +# load_slider() restores a slider object from session code. +########################################################################## +procedure load_slider(r, o) + local dir + + r.filter := ("" ~== o.num) + r.typ := o.typ + o.lbl ? { + r.min := tab(upto(",")); move(1) + r.max := tab(upto(",")); move(1) + r.value := tab(0) + } + + r.v := slider_vidget(r.id, r.typ, r.x, r.y, r.w, r.h) + VRemove(ROOT, r.v, 1) +end + +########################################################################## +# save_slider() augments the record for saving a slider object. +########################################################################## +procedure save_slider(r, o) + r.typ := o.typ + r.lbl := o.min || "," || o.max || "," || o.value + r.sty := if r.w > r.h then "h" else "v" + r.num := o.filter + return +end + +########################################################################## +# display_slider_atts() displays the attribute sheet with the current +# attributes for the given slider instance. +########################################################################## +procedure display_slider_atts(object) + local t, s + + t := table() + t["_filter"] := object.filter + t["a_id"] := object.id + t["b_callback"] := object.proc + t["c_x"] := object.x + t["d_y"] := object.y - CANVASY + t["g_lefttop"] := object.min + t["h_initial"] := object.value + t["i_rightbot"] := object.max + + if object.w > object.h then { + t["j_orientation"] := "horizontal" + t["e_length"] := object.w + t["f_width"] := object.h + } + else { + t["j_orientation"] := "vertical" + t["e_length"] := object.h + t["f_width"] := object.w + } + + repeat { + s := slider_dialog(t) + if s == "Cancel" then + fail + + if illegal(t["a_id"], "ID", "s") | + illegal(t["b_callback"], "Callback", "p") | + illegal(t["c_x"], "X", "i") | + illegal(t["d_y"], "Y", "i") | + illegal(t["f_width"], "Width", VSlider_MinWidth) | + illegal(t["e_length"], "Length", t["f_width"] * VSlider_MinAspect) | + illegal(t["g_lefttop"], "Left / Top", "n") | + illegal(t["h_initial"], "Initial", "n") | + illegal(t["i_rightbot"], "Right / Bottom", "n") + then + next + + if not ((t["g_lefttop"] <= t["h_initial"] <= t["i_rightbot"]) | + (t["g_lefttop"] >= t["h_initial"] >= t["i_rightbot"])) then { + Notice("Initial value is not between the two extremes") + next + } + + object.filter := t["_filter"] + object.id := t["a_id"] + object.proc := t["b_callback"] + object.min := t["g_lefttop"] + object.value := t["h_initial"] + object.max := t["i_rightbot"] + unfocus_object(object) + if t["j_orientation"] == "horizontal" then + move_object(object, + t["c_x"], t["d_y"] + CANVASY, t["e_length"], t["f_width"]) + else + move_object(object, + t["c_x"], t["d_y"] + CANVASY, t["f_width"], t["e_length"]) + focus_object(object) + break + } +end + +#===<<vib:begin>>=== modify using vib; do not remove this marker line +procedure slider_dialog(win, deftbl) +static dstate +initial dstate := dsetup(win, + ["slider_dialog:Sizer::1:0,0,389,276:",], + ["_cancel:Button:regular::204,225,50,30:Cancel",], + ["_filter:Button:checkno:1:270,132,69,20:filter",], + ["_okay:Button:regular:-1:139,224,50,30:Okay",], + ["a_id:Text::40:13,14,360,19:ID: \\=",], + ["b_callback:Text::40:13,35,360,19:callback: \\=",], + ["c_x:Text::3:13,62,101,19: x: \\=",], + ["d_y:Text::3:13,83,101,19: y: \\=",], + ["e_length:Text::3:13,109,101,19: length: \\=",], + ["f_width:Text::3:13,130,101,19: width: \\=",], + ["g_lefttop:Text::10:181,62,192,19: top / left: \\=",], + ["h_initial:Text::10:181,83,192,19: initial: \\=",], + ["i_rightbot:Text::10:181,104,192,19:bottom / right: \\=",], + ["j_orientation:Choice::2:15,156,99,42:",, + ["vertical","horizontal"]], + ) +return dpopup(win, deftbl, dstate) +end +#===<<vib:end>>=== end of section maintained by vib diff --git a/ipl/gpacks/vib/vibtalk.icn b/ipl/gpacks/vib/vibtalk.icn new file mode 100644 index 0000000..1ffa2d4 --- /dev/null +++ b/ipl/gpacks/vib/vibtalk.icn @@ -0,0 +1,193 @@ +############################################################################ +# +# vibtalk.icn -- procedures involving dialogue windows +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$include "vibdefn.icn" + +global ADD_TALK, DEL_TALK + +########################################################################## +# dialogue() defines pop-up window templates for the various kinds +# of pop-up windows utilized within VIB. +########################################################################## +procedure dialogue() + local tempx, tempy, howmany, where + + ADD_TALK := Vdialog(&window, PAD, PAD) + howmany := Vtext(&window, "Insert ", , 1, 2, &digits) + where := Vtext(&window, "item(s) after item ", , 2, 2, &digits) + tempy := 0 + tempx := 0 + VRegister(ADD_TALK, howmany, tempx, tempy) + tempx +:= howmany.aw + 8 + VRegister(ADD_TALK, where, tempx, tempy) + tempy +:= (3 * PAD)/2 + VInsert(ADD_TALK, Vbutton(&window, "Okay", , V_OK, , 80, 20), 20, tempy) + VInsert(ADD_TALK, Vbutton(&window, "Cancel", , V_CANCEL, , 80, 20),120,tempy) + VFormat(ADD_TALK) + + DEL_TALK := Vdialog(&window, PAD, PAD) + howmany := Vtext(&window, "delete item(s) ", , 1, 2, &digits) + where := Vtext(&window, "thru ", , 2, 2, &digits) + tempy := 0 + tempx := 0 + VRegister(DEL_TALK, howmany, tempx, tempy) + tempx +:= howmany.aw + 8 + VRegister(DEL_TALK, where, tempx, tempy) + tempy +:= (3 * PAD)/2 + VInsert(DEL_TALK, Vbutton(&window, "Okay", , V_OK, , 80, 20), 20, tempy) + VInsert(DEL_TALK, Vbutton(&window, "Cancel", , V_CANCEL, , 80, 20),120,tempy) + VFormat(DEL_TALK) +end + +########################################################################## +# open_session() asks for a file name and opens it as the current session. +########################################################################## +procedure open_session() + local fname + + repeat { + case OpenDialog("file to open: ") of { + "Okay": { + fname := def_extn(dialog_value) + if load_session(fname) then { + SESSION := fname + label_session() + return + } + Notice("Cannot open file " || fname) + } + "Cancel": + fail + } + } + return +end + +########################################################################## +# flush_session() asks whether the current session should be saved first. +# It fails if cancelled. +########################################################################## +procedure flush_session() + + if /DIRTY then + return # nothing needs saving + + return vib_save_as("save session first? ", SESSION) # fails if cancelled +end + +########################################################################## +# vib_save_as() asks for a file name and saves the session. +########################################################################## +procedure vib_save_as(prompt, def) + local fname + + repeat { + case SaveDialog(prompt, def) of { + "Yes": { + fname := def_extn(dialog_value) + if close(open(fname)) & not ok_overwrite(fname) then + next + if save_session(fname) then { + SESSION := fname + label_session() + return + } + } + "No": return + "Cancel": fail + } + } +end + +########################################################################## +# def_extn(fname) adds a ".icn" extension to a file name, if appropriate. +########################################################################## +procedure def_extn(fname) + + if not upto('.', fname) then + fname ||:= ".icn" + return fname +end + +########################################################################## +# ok_overwrite() is called to display a dialogue window for confirming +# the over-writing of a file. It is assumed that it +# is always okay to overwrite the current session. +########################################################################## +procedure ok_overwrite(fname) + if fname == SESSION then + return + + return "Okay" == Dialog( + "File " || fname || " exists. Overwrite?", , , , ["Okay", "Cancel"]) +end + +########################################################################## +# label_session() sets the window and icon labels. +########################################################################## +procedure label_session() + WAttrib("label=" || SESSION, "iconlabel=" || SESSION) +end + +########################################################################## +# illegal() posts a notice and succeeds if a value is illegal. +# +# val is the value to test. +# label is its label. +# how is how to test: +# "p" procedure name, or empty +# "s" general VIB string -- no : \ " +# "l" label string -- can include : +# "n" any numeric value +# "i" any integer value +# <min> any integer of at least <min> +########################################################################## +procedure illegal(val, label, how) + local m, s + + if case how of { + "p": { m := CBMASK; s := "must be a valid identifier" } + "s": { m := IDMASK; s := "cannot contain `\\' or `\"' or `:'" } + "l": { m := LBMASK; s := "cannot contain `\\' or `\"'" } + } + then val ? { + tab(many(m)) + if not pos(0) | (how == "p" & any(&digits, val)) then { + Notice(label || " value " || s) + return + } + else fail + } + + if *val == 0 then { + Notice(label || " value must be specified") + return + } + + if how === "n" then { + if not numeric(val) then { + Notice(label || " value must be numeric") + return + } + else fail + } + + if not integer(val) then { + Notice(label || " value must be an integer") + return + } + + if val < integer(how) then { + Notice(label || " value must not be less than " || how) + return + } + + fail # that is, the value is legal +end diff --git a/ipl/gpacks/vib/vibtext.icn b/ipl/gpacks/vib/vibtext.icn new file mode 100644 index 0000000..bdcfb9b --- /dev/null +++ b/ipl/gpacks/vib/vibtext.icn @@ -0,0 +1,163 @@ +############################################################################ +# +# vibtext.icn -- procedures for defining a text object +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ + +$include "vdefns.icn" +$include "vibdefn.icn" + +########################################################################## +# text_input_obj: +# v : vidget used for drawing text input object +# proc : name of user callback procedure +# id : unique means of identifying instance +# x,y,w,h : bounding box +# label : label of text input object +# value : (editable) value of text input object +# length : max number of chars that value can hold +# focus : should focus lines be drawn around this object? +########################################################################## +record text_input_obj(v, proc, id, x, y, w, h, label, value, length, focus) + +########################################################################## +# create_text_input() creates a text instance and draws the text object if +# it is a first class object. +########################################################################## +procedure create_text_input(x, y, label, value, length) + local r, id + + id := next_id("text_input") + r := text_input_obj(, "text_input_cb" || id, "text_input" || id, + x, y, 0, 0, label, value, length, 0) + r.v := Vtext(ROOT, x, y, APPWIN, label || "\\=" || value, , id, length) + r.w := r.v.aw + r.h := r.v.ah + VRemove(ROOT, r.v, 1) + return r +end + +########################################################################## +# draw_text_input() draws the given text object. +########################################################################## +procedure draw_text_input(r) + r.length := r.v.MaxChars +:= (r.w - r.v.aw) / VFWidth + VResize(r.v) + VDraw(r.v) + return r +end + +########################################################################## +# update_text_input_bb() makes resizing work a character at a time. +########################################################################## +procedure update_text_input_bb(object) + local wxv, n + + wxv := object.v.aw - VFWidth * object.v.MaxChars # width excluding value + n := (object.w - wxv) / VFWidth # num chars for value + n <:= 1 + n <:= *object.value + object.w := wxv + VFWidth * n # force width to char boundary + object.h := object.v.ah # disallow height change +end + +########################################################################## +# load_text_input() restores a text object from session code. +########################################################################## +procedure load_text_input(r, o) + o.lbl ? { + r.label := tab(find("\\\\=")) + move(3) + r.value := tab(0) + } + r.length := o.num + r.v := Vtext(ROOT, r.x,r.y, APPWIN, r.label||"\\="||r.value,, r.id, r.length) + r.w := r.v.aw + r.h := r.v.ah + VRemove(ROOT, r.v, 1) +end + +########################################################################## +# save_text_input() augments the record for saving a text_input object. +########################################################################## +procedure save_text_input(r, o) + r.typ := "Text" + r.lbl := image(o.label)[2:-1] || "\\\\=" || image(o.value)[2:-1] + r.num := o.length + return +end + +########################################################################## +# display_text_input_atts() displays the attribute sheet with the current +# attributes for the given text instance. +########################################################################## +procedure display_text_input_atts(object) + local t + + t := table() + t["a_id"] := object.id + t["b_callback"] := object.proc + t["c_x"] := object.x + t["d_y"] := object.y - CANVASY + t["e_label"] := object.label + t["f_value"] := object.value + t["g_length"] := object.length + + repeat { + if text_dialog(t) == "Cancel" then + fail + + if illegal(t["a_id"], "ID", "s") | + illegal(t["b_callback"], "Callback", "p") | + illegal(t["c_x"], "X", "i") | + illegal(t["d_y"], "Y", "i") | + illegal(t["e_label"], "Label", "l") | + illegal(t["f_value"], "Value", "l") | + illegal(t["g_length"], "Length", 1) | + illegal(t["g_length"], "Length", *t["f_value"]) + then + next + + object.id := t["a_id"] + object.proc := t["b_callback"] + object.label := t["e_label"] + object.value := t["f_value"] + object.length := t["g_length"] + + unfocus_object(object) + EraseArea(object.x, object.y, object.w, object.h) + + object.v.MaxChars := object.length + object.v.s := object.label + VSetState(object.v, object.value) + VResize(object.v) + object.w := object.v.aw + + move_object(object, t["c_x"], t["d_y"] + CANVASY) + focus_object(object) + break + } +end + +#===<<vib:begin>>=== modify using vib; do not remove this marker line +procedure text_dialog(win, deftbl) +static dstate +initial dstate := dsetup(win, + ["text_dialog:Sizer::1:0,0,460,230:",], + ["_cancel:Button:regular::250,180,50,30:Cancel",], + ["_okay:Button:regular:-1:180,180,50,30:Okay",], + ["a_id:Text::40:13,14,360,19:ID: \\=",], + ["b_callback:Text::40:13,35,360,19:callback: \\=",], + ["c_x:Text::3:13,62,101,19: x: \\=",], + ["d_y:Text::3:13,83,101,19: y: \\=",], + ["e_label:Text::50:13,109,430,19: label: \\=",], + ["f_value:Text::50:13,130,430,19: value: \\=",], + ["g_length:Text::3:258,83,185,19:maximum value length: \\=",], + ) +return dpopup(win, deftbl, dstate) +end +#===<<vib:end>>=== end of section maintained by vib |