############################################################################ # # 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