summaryrefslogtreecommitdiff
path: root/ipl/gprocs/navitrix.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/gprocs/navitrix.icn')
-rw-r--r--ipl/gprocs/navitrix.icn279
1 files changed, 279 insertions, 0 deletions
diff --git a/ipl/gprocs/navitrix.icn b/ipl/gprocs/navitrix.icn
new file mode 100644
index 0000000..ad8a79a
--- /dev/null
+++ b/ipl/gprocs/navitrix.icn
@@ -0,0 +1,279 @@
+############################################################################
+#
+# File: navitrix.icn
+#
+# Subject: Procedures to perform file navigation
+#
+# Author: Ralph E. Griswold
+#
+# Date: July 10, 2002
+#
+############################################################################
+#
+# This file is in the public domain.
+#
+############################################################################
+#
+# This package provides an interface for file navigation. It is
+# intended for use with another application with a visual interface.
+#
+############################################################################
+#
+# The code is based on Unix but may work in other Unix-like environments.
+#
+# Directories are shown with a trailing slash. Clicking on a directory
+# moves there. Clicking on a file name selects it. The text of the
+# button used to dismiss the navigator is put in the global variable
+# nav_state, while the name of the selected file is put in the global
+# variable nav_file.
+#
+# nav_keyboard() processes keyboard shortcuts. A return character is
+# equivalent to clicking on the Okay button. Other characters cause
+# the top list entry to be positioned at a name that starts with or is
+# close to the character.
+#
+# The other application needs only to know this:
+#
+# The navigator is initialized by calling nav_init(). This opens a
+# hidden window, assigned to the global variable nav_window, for
+# the navigator. It also assigns the navigator root vidget to the
+# global variable nav_root.
+#
+# To use the navigator, the other application needs to change the
+# canvas status nav_window to normal so it can accept user events
+# and hide it again when it has been "dismissed". The navigator
+# puts the selected file in nav_file as mentioned above.
+#
+# If the application wants to support the navigator's keyboard
+# shortcuts, it needs to set the shortcut procedure to nav_keyboard
+# when the navigator window is active.
+#
+# A typical event loop for using the navigator is:
+#
+# repeat { # event loop
+# case Active() of {
+# &window : { # application window
+# root_cur := root
+# shortcuts_cur := shortcuts
+# }
+# nav_window : { # navigation window
+# root_cur := nav_root
+# shortcuts_cur := nav_keyboard
+# }
+# }
+# ProcessEvent(root_cur, , shortcuts_cur)
+# case nav_state of {
+# &null : next
+# "Okay" : load_pattern()
+# }
+# nav_state := &null
+# WAttrib(nav_window, "canvas=hidden")
+# }
+#
+# where process_file() is a procedure that does something with the
+# file.
+#
+# Note that the value of nav_state determines what needs to be done. It is
+# null when the navigator has not been used since the last event. If
+# the navigator is dismissed with "Cancel" instead of "Okay", nothing
+# needs to be done except hide the navigator window and set the nav_state
+# to null.
+#
+# Coupled with this is a procedure (or more than one) that makes the
+# navigator window visible, as in
+#
+# procedure open_cb()
+# WAttrib(nav_window, "canvas=normal")
+# ...
+# return
+# end
+#
+# If there is more than one use of the navigator, the callbacks that
+# enable it can set process_file to the appropriate companion procedure.
+#
+############################################################################
+#
+# Requires: Version 9 graphics, UNIX
+#
+############################################################################
+#
+# Links: vsetup
+#
+############################################################################
+
+link vsetup
+
+$include "keysyms.icn"
+
+global directory
+global dir
+global file_list
+global files
+
+# Globals used to communicate with the application that uses the navigator
+
+global nav_file
+global nav_root
+global nav_state
+global nav_vidgets
+global nav_window
+
+procedure nav_init()
+ local window_save, atts
+
+ window_save := &window # save current subject window
+ &window := &null # clear for new subject
+ atts := navig_atts()
+ put(atts, "canvas=hidden")
+ (WOpen ! atts) | stop("*** can't open navigation window")
+ nav_vidgets := navig() # initialize interface
+ nav_window := &window # name navigation window
+ &window := window_save # restore previous subject window
+
+ files := nav_vidgets["files"]
+ nav_root := nav_vidgets["root"]
+
+ nav_file := &null
+
+ nav_refresh()
+
+ return
+
+end
+
+procedure nav_files_cb(vidget, value)
+ static last_file, last_time
+
+ initial {
+ last_file := ""
+ last_time := 0
+ }
+
+ if /value then {
+ last_time := 0
+ return
+ }
+
+ if value ?:= tab(upto('/')) then {
+ chdir(value)
+ nav_refresh()
+ return
+ }
+
+ nav_file := value
+
+ if (value == last_file) then {
+ last_file := ""
+ nav_state := "Okay"
+ return
+ }
+
+ last_time := 0
+ last_file := value
+
+ return
+
+end
+
+procedure nav_refresh()
+ local ls, input
+ static x, y
+
+ initial {
+ x := nav_vidgets["placeholder"].ax
+ y := nav_vidgets["placeholder"].ay
+ directory := ""
+ }
+
+ input := open("pwd", "p")
+
+ WAttrib( nav_window, "drawop=reverse")
+ DrawString(nav_window, x, y, directory)
+ DrawString(nav_window, x, y, directory := !input)
+ WAttrib(nav_window, "drawop=copy")
+
+ close(input)
+
+ file_list := []
+
+ ls := open("ls -a -p .", "p")
+
+ every put(file_list, !ls)
+
+ VSetItems(files, file_list)
+
+ close(ls)
+
+ return
+
+end
+
+procedure nav_okay_cb()
+
+ if /nav_file then {
+ Notice("No file selected.")
+ fail
+ }
+
+ nav_state := "Okay"
+
+ return
+
+end
+
+procedure nav_keyboard(e)
+
+ case e of {
+ "\r" : nav_okay_cb()
+ Key_Home : VSetState(files, 1)
+ Key_End : VSetState(files, *file_list)
+ default : if type(e) == "string" then nav_locate(e)
+ }
+
+ return
+
+end
+
+procedure nav_locate(e)
+ local i
+ static pos
+
+ initial pos := list(1)
+
+ every i := 1 to *file_list do {
+ if file_list[i] >>= e then break
+ }
+
+ pos[1] := i
+
+ VSetState(files, pos)
+
+ return
+
+end
+
+procedure nav_cancel_cb()
+
+ nav_state := "Cancel"
+
+ return
+
+end
+
+#===<<vib:begin>>=== modify using vib; do not remove this marker line
+procedure navig_atts()
+ return ["size=294,412", "bg=pale gray", "label=Navitrix"]
+end
+
+procedure navig(win, cbk)
+return vsetup(win, cbk,
+ ["navig:Sizer:::0,0,294,412:Navitrix",],
+ ["cancel:Button:regular::86,378,49,20:Cancel",nav_cancel_cb],
+ ["files:List:w::13,50,273,314:",nav_files_cb],
+ ["okay:Button:regular::21,378,49,20:Okay",nav_okay_cb],
+ ["placeholder:Button:regularno::20,22,65,17: ",],
+ ["refresh:Button:regular::224,378,56,20:Refresh",nav_refresh],
+ ["border:Rect:grooved::18,374,55,28:",nav_okay_cb],
+ )
+end
+#===<<vib:end>>=== end of section maintained by vib