############################################################################ # # File: wopen.icn # # Subject: Procedures for graphics input/output # # Authors: Gregg M. Townsend and Ralph E. Griswold # # Date: April 15, 2002 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # These procedures provide window input and output using "W" names as # substitutes for standard input and output functions. WOpen() opens # and returns a window; the result is also assigned to &window if # &window is null. # # WOpen(attrib, ...) opens and returns a window. # # WRead(W) reads a line from a window. # # WReads(W, i) reads i characters from a window. # # WWrite(W, s, ...) writes a line to window. # # WWrites(W, s, ...) writes a partial line to window. # # WDelay(W, n) flushes a window, then delays n milliseconds. # default: n = 1 # # WClose(W) closes a window; # if W === &window, sets &window to &null. # # WDone(), WQuit(), QuitCheck(), and QuitEvents() incorporate knowledge # of the Icon standard set of "quit" events, currently the letters # "q" or "Q". The procedures themselves are trivial. # # WQuit() consumes unread window events and succeeds if a quit event # is seen. It does not wait. WDone() waits until a quit event is read, # then exits the program. QuitCheck(ev) calls exit() if its parameter # is a quit event; QuitCheck can be used with the vidget package as a # default event handler. QuitEvents() generates the standard set of # quit events. # # ZDone() is a zooming version of WDone(). If the window is resized # while waiting for a quit event, its contents are zoomed to fill the # new size. Zooming to a multiple of the original size can also be # accomplished by typing a nonzero digit into the window. # # SubWindow(W, x, y, w, h) produces a subwindow by creating and # reconfiguring a clone of the given window. The original window # is not modified. In the clone, which is returned, clipping # bounds are set by the given rectangle and the origin is # set at the rectangle's upper left corner. # ############################################################################ # # Requires: Version 9 graphics # ############################################################################ link gpxop procedure WOpen(args[]) push(args, "g") push(args, "") if /&window then return &window := open ! args else return open ! args end procedure WRead(window) if /window then window := \&window | runerr(140, &window) return read(window) end procedure WReads(window, i) static type initial type := proc("type", 0) # protect attractive name if /window then window := \&window | runerr(140, &window) else if type(window) ~== "window" then { i := window window := \&window | runerr(140, &window) } return reads(window, i) end procedure WWrite(args[]) static type initial type := proc("type", 0) # protect attractive name if not (type(args[1]) == "window") then push(args, \&window) | runerr(140, &window) return write ! args end procedure WWrites(args[]) static type initial type := proc("type", 0) # protect attractive name if not (type(args[1]) == "window") then push(args, \&window) | runerr(140, &window) return writes ! args end procedure WDelay(window, n) static delay, type initial { delay := proc("delay", 0) # protect attractive names type := proc("type", 0) } if /window then window := \&window | runerr(140, &window) else if type(window) ~== "window" then { n := window window := \&window | runerr(140, &window) } /n := 1 integer(n) | runerr(101, n) WFlush(window) delay(n) return window end procedure WClose(window) if /window then window := \&window | runerr(140, &window) if window === &window then &window := &null return close(window) end procedure QuitEvents() suspend !"qQ" end procedure QuitCheck(ev) if ev === QuitEvents() then exit() return end procedure WQuit(win) /win := &window while *Pending(win) > 0 do if Event(win) === QuitEvents() then return win fail end procedure WDone(win) /win := &window until Event(win) === QuitEvents() exit() end # ZDone(win) -- like WDone(), but zoom window if resized while waiting procedure ZDone(win) local org, e, w, h, ww, hh, x0, y0 /win := &window x0 := -WAttrib(win, "dx") y0 := -WAttrib(win, "dy") w := WAttrib(win, "width") h := WAttrib(win, "height") org := WOpen("width=" || w, "height=" || h, "canvas=hidden") | WDone() CopyArea(win, org, x0, y0) WAttrib(win, "resize=on") while e := Event(win) do case e of { QuitEvents(): exit() &resize: Zoom(org, win, , , , , x0, y0) !"123456789": { ww := e * w hh := e * h WAttrib(win, "width=" || ww, "height=" || hh) Zoom(org, win, , , , , x0, y0, ww, hh) } } end procedure SubWindow(win, x, y, w, h) static type initial type := proc("type", 0) # protect attractive name if type(win) ~== "window" then return SubWindow((\&window | runerr(140)), win, x, y, w) /x := -WAttrib(win, "dx") /y := -WAttrib(win, "dy") /w := WAttrib(win, "width") - (x + WAttrib(win, "dx")) /h := WAttrib(win, "height") - (y + WAttrib(win, "dy")) if w < 0 then x -:= (w := -w) if h < 0 then y -:= (h := -h) win := Clone(win, "dx=" || WAttrib(win, "dx") + x, "dy=" || WAttrib(win, "dy") + y) Clip(win, 0, 0, w, h) GotoRC(win, 1, 1) return win end