############################################################################ # # File: getcolrs.icn # # Subject: Procedures for getting color palette # # Author: Ralph E. Griswold # # Date: May 2, 2001 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # These procedures support the interactive selection of colors. # ############################################################################ # # Requires: Version 9 graphics # ############################################################################ # # Links: colrlist, dsetup, interact # ############################################################################ link colrlist, dsetup, interact global save_colortbl_name $define CellSize 16 $define ColorCols 16 $define ColorRows 16 $define ColorField 20 $define NumberField 3 $define WPad 20 $define HPad 45 global colors global colortbl global palette record colorspec(palette, colors) procedure color_palette() local pal_win, e, number, color_win, x, y, c, i static windows, attribs, colors_tmp, clist, palettes initial { windows := table() attribs := table() attribs["palette"] := "c3" palettes := table() # set up palette colors every clist := ("c" || (1 to 6)) | ("g" || (16 | 64)) do palettes[clist] := colrplte(clist) | { Notice("Internal error") exit() } } if colors_dl(attribs) == "Cancel" then fail clist := palettes[attribs["palette"]] color_win := palette_win("color list", WAttrib("width") + WPad, 0) | fail pal_win := palette_win("palette", WAttrib("width") + WPad, WAttrib(color_win, "height") + HPad) | fail i := 0 every y := 1 + (0 to ColorCols) * CellSize do every x := 1 + (0 to ColorRows) * CellSize do { Fg(pal_win, clist[i +:= 1]) | break break FillRectangle(pal_win, x, y, CellSize - 1, CellSize - 1) } colors_tmp := [] x := y := 1 repeat { e := Event(pal_win) if &meta & (map(e) == "q") then break if e === (&lpress | &rpress | &mpress) then { if ((&x % CellSize) | (&y % CellSize)) = 0 then next # on border put(colors_tmp, c := Pixel(pal_win, &x, &y, 1, 1)) Fg(color_win, c) FillRectangle(color_win, x, y, CellSize - 1, CellSize - 1) x +:= CellSize if (x > ColorCols * CellSize) then { x := 1 y +:= CellSize if y > (ColorRows * CellSize) then break } } } WAttrib(pal_win, "canvas=hidden") EraseArea(pal_win) WClose(color_win) if *colors_tmp = 0 then return Notice("Empty palette") colors := colors_tmp if OpenDialog("Palette name:") == "Cancel" then fail palette := dialog_value colortbl[palette] := colors return colors_tmp end procedure edit_colors(colors) local color_win, x, y color_win := palette_win("color list", WAttrib("width") + WPad, 0) | fail x := y := 1 every Fg(color_win, !colors) do { FillRectangle(color_win, x, y, CellSize - 1, CellSize - 1) x +:= CellSize if (x > ColorCols * CellSize) then { x := 1 y +:= CellSize if y > (ColorRows * CellSize) then break } } Event(color_win) WClose(color_win) end procedure palette_win(label, xoff, yoff) local win, x, y win := WOpen("width=" || (ColorCols * CellSize), "height=" || (ColorRows * CellSize), "label=" || label, "bg=black", "fg=white", "posx=" || (WAttrib("posx") + xoff), "posy=" || (WAttrib("posy") + yoff)) | return Notice("Cannot open window for palette selection") WAttrib(win, "fillstyle=textured") Pattern(win, "checkers") Bg(win, "very dark gray") every x := 1 + (0 to ColorRows) * CellSize do every y := 1 + (0 to ColorCols) * CellSize do FillRectangle(win, x, y, CellSize - 1, CellSize - 1) WAttrib(win, "fillstyle=solid") Bg(win, "black") return win end # This procedure allows the users to provide lists of colors, widths, and # blend information. # # If i = 0 then only integers are allowed. # If i = 1 then only color specifications are allowed. # If i = 2 then both integers and color specifications are allowed. This # is for blend information. procedure get_list(i) local n, list_tmp, x if Dialog("Number of entries", , 2, NumberField, ["Okay", "Cancel"]) == "Cancel" then fail n := (0 < integer(dialog_value[1])) | return Notice("Invalid number specification") if Dialog("Values", , list(n, ""), ColorField, ["Okay", "Cancel"]) == "Cancel" then fail list_tmp := [] every x := !dialog_value do { if *x = 0 then next # skip empty fields case i of { 0: put(list_tmp, integer(x)) | return Notice("Invalid width") 1: put(list_tmp, ColorValue(x)) | return Notice("Invalid color") 2: put(list_tmp, ColorValue(x) | (\x & integer(x))) | return Notice("Invalid blend value:", x) } } if *list_tmp = 0 then return Notice("Empty list") return list_tmp end procedure color_blend() local colors_tmp colors_tmp := [] every put(colors_tmp, Blend ! get_list(2)) | fail # accept counts return colors_tmp end procedure get_colors(s) return case s of { "palette": color_palette() "file": unsupported() "list": get_list(1) "blend": color_blend() default: unsupported() } end procedure select_color(palette) local clist,k clist := [] every k := key(colortbl) do if \colortbl[k] then put(clist, k) if *clist = 0 then { Notice("No colors are available") fail } SelectDialog("Select color list:", sort(clist), palette) == "Okay" | fail palette := dialog_value colors := colortbl[palette] return end procedure save_colortbl() local output, temp, n, clist if /save_colortbl_name then return save_colortbl_as() output := open(save_colortbl_name, "w") | { Notice("Can't open save file for writing") fail } temp := sort(colortbl, 3) while n := get(temp) do { clist := \get(temp) | next writes(output, n, ":") every writes(output, !clist, " ") write(output) } close(output) return end procedure load_colortbl() local line, clist, tbl, name load_file("Load color table:") == "Okay" | fail tbl := table() while line := read(dialog_value) do { line ? { name := tab(upto(':')) | { Notice("Invalid color table.") fail } move(1) clist := [] while put(clist, tab(upto(' '))) do move(1) tbl[name] := clist } } colortbl := tbl palette := name colors := clist close(dialog_value) return end procedure save_colortbl_as() local n, clist, temp save_as("Save color table:") == "Yes" | fail temp := sort(colortbl, 3) while n := get(temp) do { clist := \get(temp) | next writes(dialog_value, n, ":") every writes(dialog_value, !clist, " ") write(dialog_value) } image(dialog_value) ? { ="file(" save_colortbl_name := tab(upto(')')) } close(dialog_value) return end procedure delete_color() local clist, k if *colortbl = 0 then { Notice("No colors are available") fail } clist := [] every k := key(colortbl) do if \colortbl[k] then put(clist, k) SelectDialog("Delete color:", sort(clist), palette) == "Okay" | fail TextDialog("Delete " || dialog_value || "?") == "Okay" | fail colortbl[dialog_value] := &null return end procedure delete_colortbl() TextDialog("Delete entire color table?") == "Okay" | fail colortbl := table() return end #===<>=== modify using vib; do not remove this marker line procedure colors_dl(win, deftbl) static dstate initial dstate := dsetup(win, ["colors_dl:Sizer::1:0,0,161,249:colors",], ["cancel:Button:regular::83,214,50,20:Cancel",], ["label1:Label:::11,19,56,13:Palette:",], ["okay:Button:regular:-1:15,213,50,20:Okay",], ["palette:Choice::8:83,16,50,168:",, ["c1","c2","c3","c4","c5", "c6","g16","g64"]], ) return dpopup(win, deftbl, dstate) end #===<>=== end of section maintained by vib