summaryrefslogtreecommitdiff
path: root/ipl/gprocs/colorway.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/gprocs/colorway.icn')
-rw-r--r--ipl/gprocs/colorway.icn470
1 files changed, 470 insertions, 0 deletions
diff --git a/ipl/gprocs/colorway.icn b/ipl/gprocs/colorway.icn
new file mode 100644
index 0000000..1324286
--- /dev/null
+++ b/ipl/gprocs/colorway.icn
@@ -0,0 +1,470 @@
+############################################################################
+#
+# File: colorway.icn
+#
+# Subject: Procedures to manipulate color ways
+#
+# Author: Ralph E. Griswold
+#
+# Date: August 3, 2000
+#
+############################################################################
+#
+# This file is in the public domain.
+#
+############################################################################
+#
+# Note: This file contains procedures that can be linked by programs
+# to add a visual interface, including programs that have one of their
+# own.
+#
+# These procedures support the interactive creation and modification of
+# color ways. ("Color way" is a the term used in the fashion industry for
+# a list of colors used in coordination for fabric design or other
+# decorative purposes. Think color scheme if you like.)
+#
+############################################################################
+#
+# A color way is represented by a list of color specifications. A
+# color specification consists of a name and an associated color.
+# Color ways are presented in alphabetical order of their color names,
+# with the name at the left and a swatch for the corresponding color
+# at the right of the name.
+#
+# The "edit" button is used to switch between two modes: control and
+# edit.
+#
+# In the control mode, the interface menus and the "edit" button
+# are available. The "File" menu provides for creating a new color
+# way, loading an existing color way from a file, and saving the
+# current color way. (Only one color way can be manipulated at a time.)
+# A new color way starts empty. There also is an item to pick a colorway
+# file (which must have suffix "cw").
+#
+# The "Ways" menu allows adding and deleting color specifications from
+# the current color way. When adding, a name dialog is presented first,
+# followed by a color dialog. Color specifications are added until
+# the user cancels one of the dialogs. When deleting, all of the
+# current color specifications are listed by name, and more than one
+# can be selected for deletion.
+#
+# In the edit mode, changes can be made to the current color way. This is
+# done in the window displaying the current color way. Clicking on a name
+# in the color way window produces a dialog to change that name. (The new
+# name cannot be one already in use in the color way.) Clicking on a
+# color swatch to the right of a name beings up a color dialog for selecting
+# a new color for that name. (The same color can appear in more than one
+# color specification.)
+#
+# In the editing mode, pressing the meta key while clicking on a
+# line of the color way causes the color to be deleted.
+#
+# The editing mode is exited by typing a "q" in the color way display
+# window.
+#
+# Shortcuts exist for all interface features. @E is a shortcut for
+# entering the edit mode.
+#
+# Note: The current mode is shown by the "edit" button, which is high-
+# lighted when in the edit mode. There nonetheless can be confusion about
+# the current mode.
+#
+# Unimplemented feature: Prompting user to save color way that has been
+# modified since last save.
+#
+############################################################################
+#
+# See also: cw.icn
+#
+############################################################################
+#
+# Requires: Version 9 graphics, UNIX for "pick feature"
+#
+############################################################################
+#
+# Links: interact, io, lists, strings, tables, vsetup, xcode
+#
+############################################################################
+
+link interact
+link io
+link lists
+link strings
+link tables
+link vsetup
+link xcode
+
+global cw_active # edit-mode switch
+global cw_active_vidget # edit-mode vidget
+global cw_touched
+global cw_vidgets
+global cw_root
+global cw # current color way
+global cw_file # file name for current color way
+global cw_names # list of color way names
+global cw_col # position of color field in cw_win
+global cw_win # window for current cw
+global cw_interface # interface window
+global cw_yoff # y offset from top of interface window
+
+record colorway(table) # note: "table" does not conflict
+ # with the function name. The
+ # field contains a table.
+
+$define ui cw_ui # to avoid conflict with other VIB interfaces
+$define ui_atts cw_ui_atts
+
+$define Pad 10 # name padding
+$define Lheight 30 # line height
+$define Cwidth 100 # color width
+
+procedure cw_init()
+ local atts
+
+ atts := ui_atts()
+
+ put(atts, "posx=10", "posy=10")
+
+ cw_interface := (WOpen !atts) | stop("can't open window")
+ cw_vidgets := ui() # set up vidgets
+
+ cw_yoff := WAttrib(cw_interface, "height") + 45
+
+ cw_root := cw_vidgets["root"]
+ cw_active_vidget := cw_vidgets["active"]
+ cw_active := &null # initially inactive
+
+ return
+
+end
+
+procedure edit_cw()
+ local name
+
+ expose(cw_win)
+
+ repeat {
+ case Event(cw_win) of {
+ &lpress | &mpress | &rpress: {
+ name := cw_names[(&y / Lheight) + 1]
+ if &meta then {
+ delete(cw.table, name)
+ cw_touched := 1
+ win_cw()
+ }
+ else if &x > cw_col then {
+ if ColorDialog("Select color:", cw.table[name]) ==
+ "Cancel" then next
+ cw.table[name] := dialog_value
+ cw_touched := 1
+ win_cw()
+ }
+ else {
+ repeat {
+ if TextDialog("Change name:", , name, 60) ==
+ "Cancel" then break
+ if dialog_value[1] == name then break # no change
+ if member(cw.table, dialog_value[1]) then {
+ Notice("Name " || image(dialog_value[1]) || " exists")
+ next
+ }
+ else {
+ cw.table[dialog_value[1]] := cw.table[name]
+ delete(cw.table, name)
+ win_cw()
+ cw_touched := 1
+ break
+ }
+ }
+ }
+ }
+ "q": return control_mode()
+ }
+ }
+
+end
+
+procedure control_mode()
+
+ VSetState(cw_active_vidget, &null)
+
+ expose(cw_interface)
+
+ return
+
+end
+
+procedure active_cb(vidget, value)
+
+ cw_active := value
+
+ return
+
+end
+
+procedure way_cb(vidget, value)
+
+ case value[1] of {
+ "add @A": add_way()
+ "delete @D": delete_way()
+ }
+
+ return
+
+end
+
+procedure file_cb(vidget, value)
+
+ case value[1] of {
+ "load @L": load_cw()
+ "new @N": new_cw()
+ "pick @P": pick()
+ "quit @Q": quit()
+ "save @S": save_cw()
+ "save as": save_cw_as()
+ }
+
+ return
+
+end
+
+procedure shortcuts(e)
+
+ if &meta then case map(e) of {
+ "a": add_way()
+ "d": delete_way()
+ "e": VSetState(cw_active_vidget, 1)
+ "l": load_cw()
+ "n": new_cw()
+ "p": pick()
+ "q": quit()
+ "s": save_cw()
+ }
+
+ return
+
+end
+
+procedure add_way()
+ local name
+
+ repeat {
+ repeat {
+ if TextDialog("Add color:", "name", , 60) == "Cancel" then return
+ if \cw.table[dialog_value[1]] then {
+ Notice("Name is in use.")
+ next
+ }
+ name := dialog_value[1]
+ if ColorDialog("Choose color:") == "Cancel" then return
+ cw.table[name] := dialog_value
+ win_cw()
+ cw_touched := 1
+ next
+ }
+ }
+
+end
+
+# NOTE: Got error in line comparing dialog_value[i]: &null.
+
+procedure delete_way()
+ local i, x, count
+
+ if ToggleDialog("Delete ways:", cw_names) == "Cancel" then fail
+
+ count := 0
+
+ every i := 1 to *dialog_value do
+ if dialog_value[i] == 1 then {
+ delete(cw.table, cw_names[i])
+ count +:= 1
+ cw_touched := 1
+ }
+
+ if count > 0 then win_cw()
+
+ return
+
+end
+
+procedure load_cw()
+ local input, x
+
+ repeat {
+ if OpenDialog() == "Cancel" then fail
+ input := open(dialog_value) | {
+ Notice("Cannot open file")
+ next
+ }
+ x := xdecodet(input, "colorway") | {
+ Notice("File does not contain color way")
+ close(input)
+ next
+ }
+ cw_file := dialog_value
+ cw := x
+ win_cw()
+ expose(cw_interface)
+ close(input)
+ cw_touched := &null
+ return
+ }
+
+end
+
+
+procedure win_cw()
+ local y, name, height
+
+ WClose(\cw_win)
+
+ cw_col := 2 * Pad # in case the color way is empty
+ cw_names := (keylist(cw.table) | [])
+ cw_col := maxlen(cw_names, TextWidth) + (2 * Pad)
+
+ height := Lheight
+ height <:= Lheight * *cw.table
+
+ cw_win := WOpen("label=" || cw_file, "size=" || (cw_col + Cwidth) ||
+ "," || height, "posx=" || WAttrib(cw_interface, "posx"),
+ "posy=" || WAttrib(cw_interface, "posy") + cw_yoff) |
+ ExitNotice("Cannot open window")
+
+ y := 0
+
+ every name := !cw_names do {
+ Fg(cw_win, "black")
+ CenterString(cw_win, cw_col / 2, y + (Lheight / 2), name)
+ Fg(cw_win, cw.table[name]) | {
+ Notice("Invalid color: " || cw.table[name], "substituting black")
+ Fg(cw_win, "black")
+ }
+ FillRectangle(cw_win, cw_col, y, Cwidth, Lheight)
+ y +:= Lheight
+ }
+
+ if \cw_active then expose(cw_win)
+
+ return
+
+end
+
+procedure new_cw()
+
+ if /cw_touched then {
+ # ask if colorway is to be saved first
+ }
+
+ cw := colorway(table())
+ win_cw()
+ cw_touched := &null
+
+ return
+
+end
+
+procedure save_cw()
+ local output
+
+ repeat {
+ if SaveDialog(, cw_file) == "Cancel" then fail
+ output := open(dialog_value, "w") | {
+ Notice("Cannot open " || dialog_value || " for writing")
+ next
+ }
+ xencodet(cw, output, "colorway") |
+ ExitNotice("Internal inconsistency: color way is corrupt")
+ close(output)
+ cw_touched := &null
+ return
+ }
+
+end
+
+procedure save_cw_as()
+ local output, temp
+
+ repeat {
+ if SaveDialog("Save as:") == "Cancel" then fail
+ if dialog_value == \cw_file then {
+ temp := dialog_value
+ if TextDialog("Overwrite existing file?") == "Cancel" then next
+ dialog_value := temp
+ }
+ output := open(dialog_value, "w") | {
+ Notice("Cannot open " || dialog_value || " for writing")
+ next
+ }
+ xencodet(cw, output, "colorway") |
+ ExitNotice("Internal inconsistency: color way is corrupt")
+ close(output)
+ cw_touched := &null
+ return
+ }
+
+end
+
+procedure quit()
+
+ if \cw_touched then {
+ # ask for save if touched
+ }
+
+ exit()
+
+end
+
+# Utility procedure to let user pick an image file in the current directory.
+
+procedure pick()
+ local plist, ls, input, x
+
+ plist := filelist("*.cw") |
+ return FailNotice("Pick not supported on this platform")
+
+ if *plist = 0 then return FailNotice("No files found.")
+
+ repeat {
+ if SelectDialog("Select color way:", plist, plist[1]) == "Cancel"
+ then fail
+ input := open(dialog_value) | {
+ Notice("Cannot open file")
+ next
+ }
+ x := xdecodet(input, "colorway") | {
+ Notice("File does not contain color way")
+ close(input)
+ next
+ }
+ cw_file := dialog_value
+ cw := x
+ win_cw()
+ expose(cw_interface)
+ close(input)
+ cw_touched := &null
+ return
+ }
+
+ return
+
+end
+
+#===<<vib:begin>>=== modify using vib; do not remove this marker line
+procedure ui_atts()
+ return ["size=134,169", "bg=gray-white"]
+end
+
+procedure ui(win, cbk)
+return vsetup(win, cbk,
+ [":Sizer:::0,0,134,169:",],
+ ["active:Button:regular:1:17,38,49,20:edit",active_cb],
+ ["file:Menu:pull::2,2,36,21:File",file_cb,
+ ["new @N","load @L","pick @P","save @S","save as",
+ "quit @Q"]],
+ ["line:Line:::0,25,200,25:",],
+ ["ways:Menu:pull::40,2,36,21:Ways",way_cb,
+ ["add @A","delete @D"]],
+ )
+end
+#===<<vib:end>>=== end of section maintained by vib