[comp.windows.news] Wrappingpaper

zwicky@pterodactyl.cis.ohio-state.edu (Elizabeth D Zwicky) (04/19/89)

Well, now that wallpaper is working, I'd thought I'd give you all
another way to waste time. This one lets you waste paper, too, if you
have a PostScript printer. It also has a lot of small and not-so-small
useful tricks coded into it, and is possibly the most egregious example
of overuse of items and windows I've ever seen, much less perpetrated.
I realize that the user interface leaves something to be desired, but
my theory about a better one involves several new item types, so
I thought I'd save it for a later release.

----------------Cut Here-------------------------------------------
#! /usr/NeWS/bin/psh
% wrappingpaper:  Written and conceived by Elizabeth D. Zwicky
% Send comments to zwicky@cis.ohio-state.edu
false setautobind
%Install LiteItem if nothing else has
systemdict /Item known not { (NeWS/liteitem.ps) run } if
% Start a new dictionary; we've outgrown the default one
/partsdict dictbegin

    /name (PostScript) def % default printer name
    /tilewin null def
    /startup{ %defines all the drawing variables; it is wrapped like this
	% so that it is simple to make sure that everything will be
	% initialized both in the window and in the printer.
	/times 3 def
	/times2 4 def
	/hoffset 0 def /voffset 0 def
	/hoffset2 0 def /voffset2 0 def
	/slant 0 def /slant2 0 def
	/prerotate 0 def /prerotate2 0 def
	/prescale 1 def /prescale2 1 def
	/alternate null def  /alterdo {-1 1 scale} def
	/alternate2 null def  /alterdo2 {-1 1 scale} def
	/alterrotate 180 def /alterrotate2 180 def
	/on false def /arow false def /offrow false store
	/on2 false def /arow2 false def /offrow2 false store
	/drawone{}def /drawtwo{}def
	/dimen 25 store /dimen2 25 store
	/dimen2 25 store /dimen22 25 store
	/firsttile true def
	/firstdraw true def
	/shape null def /starty null def 
	/drawitems null def 
	/over null def 
	/startx null def 
	/tmpx 0 def /tmpy 0 def
	/tox null def /toy null def 
	/canvas null def 
	/lastx 0 def /lasty 0 def
	/execshape {shape cvx exec} def
	/tofile false def
	/n 3 def /n2 3 def /nn 3 def
	/nstarn 5 def /nstarn2 5 def /nstarnn 5 def
	/nstarangle {180 360 nstarnn div sub 3 div}  def
	/second false def /second2 false def
	/unit2 false def
	/ontop false def
    }def
    startup

    /MySliderItem SliderItem dictbegin dictend classbegin
	/XToValue { % x -> value
	    ObjectX sub
	    0 max ObjectWidth SliderWidth sub min
	    Scale div SliderMin add 
	    Round {round} {round .1 mul}ifelse
	} def
	/ValueToX{
	    Round
	    {SliderMin sub Scale mul ObjectX add}
	    {SliderMin sub Scale mul 10 mul ObjectX add}
	    ifelse
	} def
    classend def

	
    /disappear {% Takes an item  and makes it invisible
	dup /ItemCanvas get /Transparent false put 
	dup /unmap exch send  
	/ItemCanvas get /Transparent true put
    } def

    /reappear { % makes a disappeared item reappear
	dup /map exch send /paint exch send
    } def

% These are the possible smallest units

    /paisle{
	30 0 30 40 0 40 rcurveto
	-40 0 -50 -10 -50 -40 rcurveto
	5 20 30 30 30 20 rcurveto
	5 -10 10 -20 20 -20 rcurveto
	closepath 
    } def

    /ngon{ % polygon of n sides, n determined by nslider
	nn {150 nn div 0 rlineto 
	    360 360 nn div sub rotate 
	} repeat
	closepath
    } def

    /nstar{ % star of n points, n determined by nstarslider
	nstarnn { 150 nstarnn div 0 rlineto
	    180 180 nstarangle 2 mul sub sub  rotate
	    150 nstarnn div 0 rlineto
	    180 180 360 nstarnn div sub nstarangle 2 mul sub sub neg rotate
	} repeat
	closepath
    } def

    /crescent {
	40 20 40 50 0 70 rcurveto
	20 -20 20 -50 0 -70 rcurveto
	closepath
    } def

    /tri{
	70 0 rlineto 
	-35 30 rlineto 
	-35 -30 rlineto 
	closepath
    }def


% Rotation or reflection chooses how the larger pieces are made
% out of the smaller ones.

    /rotation{
	/drawone{
	    alternate
	    prerotate rotate 
	    prescale prescale scale
	    times{
		hoffset voffset rmoveto
		gsave
		slant rotate
		part stroke pause
		grestore
		hoffset neg voffset neg rmoveto
		360 times div rotate
	    }repeat 
	}store
	/rot true store
    }def

    /rotation2{
	/drawtwo {
	    alternate2
	    prerotate2 rotate
	    prescale2 prescale2 scale
	    times2{
		hoffset2 voffset2 rmoveto
		gsave
		slant2 rotate
		part2 stroke pause
		grestore
		hoffset2 neg voffset2 neg rmoveto
		360 times2 div rotate
	    }repeat
	}store
	/rot2 true store
    }def

    /reflection{
	/drawone{
	    alternate
	    prerotate rotate
	    prescale prescale scale
	    times{
		gsave
		hoffset voffset rmoveto
		slant rotate
		part stroke pause
		grestore
		gsave
		-1 1 scale
		hoffset voffset rmoveto
		slant rotate
		part stroke pause
		grestore
		360 times div rotate
	    }repeat 
	}store
	/rot false store
    }def

    /reflection2{
	/drawtwo{
	    alternate2
	    prerotate2 rotate
	    prescale2 prescale2 scale
	    times2{
		gsave
		hoffset2 voffset2 rmoveto
		slant2 rotate
		part2 stroke pause
		grestore  
		gsave
		-1 1 scale
		hoffset2 voffset2 rmoveto
		slant2 rotate
		part2 stroke pause
		grestore
		360 times2 div rotate
	    }repeat 
	}store
	/rot2 false store
    }def

    /loopstart{% precalculates values used in the tiling loops
	/hexdimen dimen def
	/hexdimen2 
	   hexdimen hexdimen mul
	   hexdimen 2 div hexdimen 2 div mul
	   sub sqrt 
	def
	/outloop height hexdimen 3 mul div ceiling cvi 1 add def
	/inloop width hexdimen2 2 mul div ceiling cvi 1 add def
	/yincr hexdimen 1.5 mul def
	/xincr hexdimen2 2 mul def
	/firstcorrect inloop xincr mul neg hexdimen2 add def
	/lastcorrect inloop xincr mul neg hexdimen2 neg add def
	/correct inloop xincr mul neg def
	/sqoutloop height dimen div ceiling cvi 1 add def
	/sqinloop width dimen div ceiling cvi 1 add def
	/hincr dimen def
	/vincr dimen2 def
	/hinloop width dimen div ceiling cvi 1 add def
	/1correct hinloop hincr mul hincr 2 div sub neg def
	/2correct hinloop hincr mul hincr 2 div add neg def
	/houtloop height dimen2 div ceiling cvi 1 add def
    }def

% These procedures actually do the tiling
    /hextile{
	/on false store /prev on store
	outloop{
	    inloop{
		0 0 moveto
		gsave drawone stroke grestore
		newpath
		ontop {0 0 moveto gsave drawtwo stroke grestore} if
		xincr 0 translate
	    } repeat 
	    arow {/on true store} {/on false store} ifelse
	    second {/on prev store} if
	    firstcorrect yincr translate
	    inloop{
		0 0 moveto
		gsave drawone stroke grestore
		newpath
		ontop {0 0 moveto gsave drawtwo stroke grestore} if
		xincr 0 translate
	    } repeat
	    /on false store
	    second {/on prev not store /prev on store} if
	    lastcorrect yincr translate
	}repeat
	0 0 moveto
	gsave drawone grestore
    } store

    /halftile{
	/on false store /prev on store
	houtloop{
	    hinloop{
		0 0 moveto
		gsave drawone stroke grestore
		newpath
		ontop {0 0 moveto gsave drawtwo stroke grestore} if
		hincr 0 translate
	    } repeat 
	    arow {/on true store} {/on false store} ifelse
	    second {/on prev store} if
	    1correct vincr translate
	    hinloop{
		0 0 moveto
		gsave drawone stroke grestore
		newpath	 
		ontop {0 0 moveto gsave drawtwo stroke grestore} if
		hincr 0 translate
	    } repeat
	    /on false store
	    second {/on prev not store /prev on store} if
	    2correct vincr translate
	}repeat
	0 0 moveto
	gsave drawone grestore
    } store

    /squaretile{
	/on false store /prev on store
	sqoutloop{
	    sqinloop{
		0 0 moveto
		gsave drawone stroke grestore
		newpath
		ontop { 0 0 moveto gsave drawtwo stroke grestore} if
		dimen 0 translate
	    } repeat
	    arow 
	    {offrow 
		{/on false store /offrow false store} 
		{/on true store /offrow true store} 
		ifelse
	    }
	    {second
		{offrow
		    {/on prev store /offrow false store}
		    {/on prev not store /prev on store /offrow true store}
		    ifelse} 
		{/on false store}
		ifelse
	    }
	    ifelse
	    dimen sqinloop mul neg 0 translate 
	    0 dimen translate
	}repeat
	0 0 moveto
	gsave drawone stroke grestore
	/offrow false store
    } store

% This sets what smallest unit is the default
    /part {ngon} def
    /part2 {crescent} def

% Sets the default for both parts to reflection
    reflection
    reflection2

% Sets the default tiling to hexagonal
    /tile{hextile}store

    /tmpstring 30 string def
    /recurse{% Given an array, write a representation of it to a file whose
	% filehandle is "tmp"
	tmp ({ ) writestring 
	    {dup type (arraytype) eq {recurse}
		{dup type (nametype) eq 
		    exch dup xcheck not
		    exch 3 1 roll and 
		    {tmp (/) writestring}
		    if 
		    tmp exch tmpstring cvs writestring 
		    tmp ( ) writestring
		} ifelse
	    } forall 
	    tmp (} ) writestring
    } def

    /dump{ % given the name of something currently defined, dump its
	% definition to a file whose filehandle is tmp using recurse
	dup tmp (/) writestring
	tmp exch tmpstring cvs writestring 
	tmp ( ) writestring 
	load dup type (arraytype) eq 
	{recurse} 
	{dup type (nametype) eq
	    exch dup xcheck not
	    exch 3 1 roll  and 
	    {tmp (/) writestring} 
	    if
	    tmp exch tmpstring cvs writestring 
	    tmp ( ) writestring
	}
	ifelse 
	tmp (def \n) writestring
    } def

    /printdump{% Use dump to print the current filing to a printer or
	% to a file
	/tmp (tmp) (w) file def
	tmp (%! \n /height 700 def  /width 500 def /pause {} def \n) writestring
	/startup dump
	tmp (startup \n) writestring
	/hoffset dump /hoffset2 dump
	/voffset dump /voffset2 dump
	/slant dump /slant2 dump
	/times dump /times2 dump
	/prerotate dump /prerotate2 dump
	/prescale dump /prescale2 dump
	/alterrotate dump /alterrotate2 dump
	/dimen dump
	/dimen2 dump
	/shape dump 
	/ontop dump
	/loopstart dump
	/second dump
	/n dump /n2 dump /nn dump
	/part load {} forall dump /part2 load {} forall dump
	tmp  (/on false def /offrow false def /execshape {shape} def \n) writestring
	/alternate dump
	/alterdo dump
	/part dump /part2 dump
	/arow dump
	/drawone dump /drawtwo dump
	/tile load {} forall dump
	/tile dump
	tmp (loopstart 0 0 moveto tile showpage \n) writestring
	tmp closefile
	tofile 
	{(cp tmp ) name append forkunix} 
	{(lpr -P) name append ( tmp)  append forkunix} 
	ifelse
    } def

% Printer dialog box
    /printwin framebuffer /new DefaultWindow send def
    100 100 200 200 /reshape printwin send
    /printcan printwin /ClientCanvas get def
    /printitems 10 dict def
    printitems begin
	/nametext 
	   (Name of File or Printer)
	   (PostScript)
	   /Bottom
   	   {}
	   printcan 100 20
	   /new TextItem send
	   10 100 /move 3 index send
	def
	/printit
	   (Print)
	   {/name printitems /nametext get /ItemValue get store
	       printdump /unmap printwin send}
	   printcan 20 20 
	   /new ButtonItem send
	   70 10 /move 3 index send
	def
	/cancel 
	   (Cancel)
	   {/unmap printwin send}
	   printcan 20 20 
	   /new ButtonItem send
	   10 10 /move 3 index send
	def
	/filecycle
	   (Print to File:)
	   [/panel_check_off /panel_check_on]
	   /Right
	   {tofile
	       {/tofile false store}
	       {/tofile true store}
	    ifelse
	   }
	   printcan 20 20
	   /new CycleItem send
	   10 65 /move 3 index send
	def
    end

    printitems forkitems

    {/PaintClient{erasepage printitems paintitems} def
	/destroy {/unmap printwin send} def
    } printwin send

% Window for the tiling
    /tilemain{
	/firsttile false store
	/tilewin framebuffer /new DefaultWindow send store
	{
	    /PaintClient{
		erasepage 
		clippath pathbbox 
		/height exch store /width exch store 
		loopstart 
		0 0 moveto 
		tile
	    }def
	    /destroy{ %Gentle destroy
		/firsttile true store
		/unmap tilewin send
		tilewin /FrameEventMgr get killprocess
	    }def 
	} tilewin send
	/reshapefromuser tilewin send
	/map tilewin send
    }def


% Window for the controls
    /itemwin framebuffer /new DefaultWindow send def

    {/PaintClient{erasepage items paintitems} def } itemwin send 
    100 100 500 310 /reshape itemwin send
    /can itemwin /ClientCanvas get def
    
% Window for Unit One
    /win framebuffer /new DefaultWindow send def
    /reshapefromuser  win send
    {
	/PaintClient{
	    erasepage 
	    clippath pathbbox 
	    /y exch def /x exch def
	    x 2 div y 2 div moveto 
	    drawone
	}def 
	/FrameLabel (Unit One) def
	/ClientMenu [
	    (Show me a tiling)
	    {first 
		{tilemain}
		{/paint tilewin send}
		ifelse}
	]/new DefaultMenu send def
    } win send

/first true def /helpwindow null def
/help {% Put up help file in window
    % Make help window
    /helpwindow framebuffer /new ScrollWindow send store
    0 0  390 460 /reshape helpwindow send
    framebuffer setcanvas 
    itemwin /FrameCanvas get getcanvaslocation  exch 200 add exch 460 sub
    /move helpwindow send
    { /NotifyUser
	{ /PaintClient helpwindow send}
	def
    } dup  helpwindow /VScrollbar get send helpwindow /HScrollbar get send

    helpwindow /ClientCanvas get setcanvas
	{
	    /PaintClient{ ClientCanvas setcanvas erasepage
		clippath pathbbox  /place exch def /urx exch def
		/lly exch def /llx exch def /width urx llx sub def
		/height place lly sub def
		HScrollbar /ItemValue get width mul neg VScrollbar /ItemValue get height mul translate
		helptext
		 { 
		     /place place 14 sub def
		     5 place moveto
		     show
		 } forall
	     } def 
	     /destroy { % Gentle destroy; does not take other things with it
		 helpwindow /IconCanvas get /Mapped false put
		 helpwindow /FrameCanvas get /Mapped false put
		 helpwindow /ClientCanvas get /Mapped false put
		 helpwindow /FrameEventMgr get killprocess
		 /first true store
	     }def
	 } helpwindow send
     /first false store
     /map helpwindow send
 } def
    /helptext [
	(This program allows you to create interesting repeating)
	(patterns and print them. It is called "wrappingpaper")
	(partly because of an earlier program named "wallpaper")
	(by the same author, and partly because it has often been)
	(suggested that the printouts would make good wrapping)
	(paper for small gifts.)
	( )
	(The repeating patterns are built up from "units" made)
	(by repeating, by rotation or rotation and reflection,)
	("parts". The parts can be moved around the axis of)
	(rotation horizontally and vertically, and scaled and tilted)
	(before the repetitions are made. The units can also be)
	(rotated as wholes. The first unit is always visible; to)
	(see the tiling, hit the tile button, and it will give you)
	(yet another window.)
	( )
	(Three possible tilings are available, with various sorts)
	(of alternation. The best way to get an idea of what the)
	(different tiling options do is to tile a single paisle.)
	(Since the paisle is neither vertically nor horizontally)
	(symmetrical, all rotations and reflections are visible)
	(when applied to it.)
	( )
	(If you choose to draw your own part, you will get a)
	(very primitive drawing window. Click to place the)
	(endpoint of the line; doubleclick to end the shape.)
	( )
	(You can add a second unit, which is currently treated just)
	(like the first one \(you can't alternate between the two )
	(units\). More features for the second unit will be added)
	(later, as will a more intuitive interface.)
 	( )
	(This program will only print to a PostScript printer.)
	(It is addictive and you may waste a lot of paper!)
	(Written and conceived by Elizabeth D. Zwicky.)
	(Send comments to zwicky@cis.ohio-state.edu)
    ] def
	

% Window for the second part
    /win2 null def /made2win false def
    /make2win{made2win not
	{/win2 framebuffer /new DefaultWindow send store
	    /reshapefromuser  win2 send
	    {
		/PaintClient{
		    erasepage 
		    clippath pathbbox 
		    /y exch def /x exch def
		    x 2 div y 2 div moveto 
		    drawtwo
		}def 
		/FrameLabel (Unit Two) def
		/ClientMenu [
		    (Show me a tiling)
		    {first 
			{tilemain}
			{/paint tilewin send}
			ifelse}
		]/new DefaultMenu send def
	    } win2 send
	    /map win2 send  /made2win true store}
	{/map win2 send}
	ifelse
    }def

% Long notify procedures
    /alternotify{ 
	ItemValue [
	    0 {/arow false store /alternate {} store /second false store itemwin items 
		/alterdocycle get disappear items /alterrotateslider get
	    disappear}
	    1 {/on false store /arow false store /second false store
		/alternate{
		    on {alterdo /on false store} {/on true store} ifelse
		} store 
		itemwin items /alterdocycle get reappear}
	    2 {/on false store /arow true store /second false store
		/alternate{ on {alterdo} if} store}
	    3 {/on false store /arow true store /second false store
		/alternate{
		    on { alterdo /on false store} {/on true store} ifelse
		} store}
	    4 {/on false store /second true store /arow false store
		/alternate{
		    on {alterdo /on false store} {/on true store} ifelse
		} store}
	] case
    } def

    /oneify{%set controls to match Unit One
	items begin
	    {hoffset setvalue} hoffsetslider send
	    {voffset setvalue} voffsetslider send
	    {slant setvalue} slantslider send 
	    {times setvalue} timesslider send
	    {n setvalue} nslider send
	    /part load {} forall dup
	    [ (ngon) {{0 setvalue} partcycle send}
		(tri) {{1 setvalue} partcycle send}
		(paisle) {{2 setvalue} partcycle send}
		(crescent) {{3 setvalue} partcycle send}
		(nstar) {{4 setvalue} partcycle send}
		(execshape) {{5 setvalue} partcycle send}
	    ] 
	    case
	    dup (ngon) eq  
	    {nslider reappear}
	    {nslider disappear}
	    ifelse
	    (nstar) eq
	    {nstarslider reappear}
	    {nstarslider disappear}
	    ifelse
	    {prerotate setvalue} rotateslider send
	    {prescale setvalue} scaleslider send
	    rot {{1 setvalue} reflectcycle send}
	    {{0 setvalue} reflectcycle send}
	    ifelse
	end
    } def
    
    /twoify{% Set controls to match Unit Two
	items begin
	    {hoffset2 setvalue} hoffsetslider send
	    {voffset2 setvalue} voffsetslider send
	    {slant2 setvalue} slantslider send 
	    {times2 setvalue} timesslider send
	    {n2 setvalue} nslider send
	    /part2 load {} forall dup
	    [ /ngon {{0 setvalue} partcycle send}
		/tri {{1 setvalue} partcycle send}
		/paisle {{2 setvalue} partcycle send}
		/crescent {{3 setvalue} partcycle send}
		/nstar {{4 setvalue} partcycle send}
		/execshape {{5 setvalue} partcycle send}
	    ] 
	    case
	    dup (ngon) eq  
	    {nslider reappear}
	    {nslider disappear}
	    ifelse
	    (nstar) eq
	    {nstarslider reappear}
	    {nstarslider disappear}
	    ifelse
	    {prerotate2 setvalue} rotateslider send
	    {prescale2 setvalue} scaleslider send
	    rot2 {{1 setvalue} reflectcycle send}
	    {{0 setvalue} reflectcycle send}
	    ifelse
	end
    }def

    /drawnotify {
	/firstdraw false store
	items /partcycle get begin 
	    /Cycle 
	    [(N-gon)(Triangle)(Paisle)(Crescent)(N-star)(NewPart)] 
	    def 
	end
	/drawwin framebuffer /new DefaultWindow send def
	/reshapefromuser drawwin send
	/canvas drawwin /ClientCanvas get store
	{
	     /destroy { % Gentle destroy; does not take other things with it
		 drawwin /IconCanvas get /Mapped false put
		 drawwin /FrameCanvas get /Mapped false put
		 drawwin /ClientCanvas get /Mapped false put
		 drawwin /FrameEventMgr get killprocess
		 /firstdraw true store
	     }def
	} drawwin send
	/startx 0 store /starty 0 store
	/tox 100 store /toy 100 store
	/shape null store
	/gstate null def
	
	canvas setcanvas
	/over currentcanvas createoverlay store
	/drawitems dictbegin
	    /shapebutton (Make a Shape) 
	    {/gstate null store 
		shape null ne {
		    canvas setcanvas
		    100 75 translate 
		    1 setgray 0 0 moveto
		    shape cvx exec stroke
		    0 setgray 
		    /shape null store 
		    /lastx 0 store /lasty 0 store
		} if 
		{
		    over setcanvas 
		    100 75 translate
		    startx starty {x y lineto} getanimated
		    waitprocess aload pop /toy exch def /tox exch def

		    canvas setcanvas
		    gstate null ne 
		       {gstate setstate} 
		       {100 75 translate}  
		    ifelse
		    startx starty moveto
		    tox toy lineto
		    /gstate currentstate store
		    gsave  stroke grestore 
		    /shape
		       mark
		       /lastx 0 store /lasty 0 store
		       {/tmpy exch store /tmpx exch store 
			   tmpx lastx sub tmpy lasty sub
			   /lastx tmpx store /lasty tmpy store 
			   /rmoveto cvx }
		        {/tmpy exch store /tmpx exch store 
			    tmpx lastx sub tmpy lasty sub
			    /lastx tmpx store /lasty tmpy store 
			    /rlineto cvx}
		        {/curveto cvx}
		        {/closepath cvx}
		        pathforall 
		        counttomark array astore exch pop
		    store 
		    startx tox eq starty toy eq and {exit} if   	   
		    /startx tox def /starty toy def
		} loop 
		/startx 0 def /starty 0 def
	    } canvas 100 20
	    /new ButtonItem send 10 10 /move 3 index send def
	dictend 
	store
	drawitems forkitems drawitems paintitems 
	{ 
	    /PaintClient{
		erasepage 
		drawitems paintitems 
		shape null ne 
		{100 75 translate 0 0 moveto shape cvx exec stroke}
		if 
	    } def
	} drawwin send
	/map drawwin send
    } def 

% Define a *lot* of items
    /items dictbegin

    /altercycle 
       (Alternation:) 
       [(No Alternation) (Alternate Items) (Alternate Rows) (Checkerboard)
          (Stretched Checkerboard) ]
       /Right
       /alternotify
        can 100 20 
       /new CycleItem send
        200 70 /move 3 index send 
    def

    /alterdocycle 
       (Do Alternate:) 
       [(Reflect Vertical) (Rotate) (Reflect Horizontal)] 
       /Right
       {unit2
	   {ItemValue{
	       0 {/alterdo2 {-1 1 scale} store}
	       1 {/alterdo2 {alterrotate2 rotate} store itemwin  items /alterrotateslider get reappear}
	       2 {/alterdo2 {1 -1 scale} store itemwin items /alterrotateslider get disappear}
	   } case  }
	   {ItemValue{
	       0 {/alterdo {-1 1 scale} store}
	       1 {/alterdo {alterrotate rotate} store itemwin items /alterrotateslider get reappear}
	       2 {/alterdo {1 -1 scale} store itemwin items /alterrotateslider get disappear}
	   } case  }
	   ifelse
       }
       can 100 20 
       /new CycleItem send 
       200 40 /move 3 index send 
    def

    /hoffsetslider 
       (Horizontal Offset:)
       [-50 50 0]
       /Right 
       {unit2 {/hoffset2 ItemValue store /paintclient win2 send}
	   {/hoffset ItemValue store /paintclient win send} ifelse}
       can 120 10
       /new SliderItem send
       10 190 /move 3 index send 
    def
    
    /voffsetslider
       (Vertical Offset:)
       [-50 50 0]
       /Right
       {unit2 {/voffset2 ItemValue store /paintclient win2 send}
	   {/voffset ItemValue store /paintclient win send} ifelse}
       can 120 10 
       /new SliderItem send 
       230 190 /move 3 index send 
    def

    /slantslider
       (Slant:)
       [-180 180 0] 
       /Right
       {unit2 {/slant2 ItemValue store /paintclient win2 send}
          {/slant ItemValue store /paintclient win send} ifelse}
       can 120 10 
       /new SliderItem send 
       48 160 /move 3 index send
    def

    /timesslider 
       (Number:)
       [1 20 3]
       /Right
       {unit2 {/times2 ItemValue store /paintclient win2 send}
	   {/times ItemValue store /paintclient win send} ifelse}
       can 120 10
       /new SliderItem send 
       110 250 /move 3 index send 
    def

    /nslider
       (N:)
       [3 20 3]
       /Right
       {unit2 {/n2 ItemValue store /nn n2 store /paintclient win2 send}
	   {/n ItemValue store /nn n store /paintclient win send} ifelse}
       can 120 10
       /new SliderItem send
       10 230 /move 3 index send
    def

    /nstarslider
       (N:)
       [3 20 5]
       /Right
       {unit2 {/nstarn2 ItemValue store /nstarnn nstarn2 store /paintclient win2 send}
	   {/nstarn ItemValue store /nstarnn nstarn store /paintclient win send} ifelse}
       can 120 10
       /new SliderItem send
       10 230 /move 3 index send
    def

    /partcycle 
       (Unit:)
       [(N-gon)(Triangle)(Paisle)(Crescent)(N-star)]
       /Right
       {unit2 
	   {ItemValue{
	       0 {/part2 {ngon} store itemwin items /nstarslider get disappear
		   items /nslider get reappear}
	       1 {/part2 {tri} store itemwin items /nslider get disappear}
	       2 {/part2 {paisle} store}
	       3 {/part2 {crescent} store}
	       4 {/part2 {nstar} store items /nstarslider get reappear}
	       5 {/part2 {execshape} store items /nstarslider get disappear}
	       
	   } case
	   /paintclient win2 send}
	   {ItemValue{
	       0 {/part {ngon} store itemwin items /nstarslider get disappear
		   items /nslider get reappear}
	       1 {/part {tri} store itemwin items /nslider get disappear}
	       2 {/part {paisle} store}
	       3 {/part {crescent} store}
	       4 {/part {nstar} store items /nstarslider get reappear}
	       5 {/part {execshape} store items /nstarslider get disappear}
	   } case
	   /paintclient win send} 
	   ifelse
       }
       can 100 20 /new CycleItem send 
       10 250 /move 3 index send 
    def

    /reflectcycle 
        (Symmetry Type:)
       [(Reflection)(Rotation)]
       /Right
       {unit2
	   {ItemValue {
	       0 {reflection2}
	       1 {rotation2}
	   } case 
	   /paintclient win2 send}
	   {ItemValue {
	       0 {reflection}
	       1 {rotation}
	   } case 
	   /paintclient win send}
	   ifelse
       }
       can 100 20
       /new CycleItem send 
       10 215 /move 3 index send 
    def

    /tilecycle
       (Tiling Type:)
       [(Hexagonal)(Half Drop)(Square)]
       /Right
       {
	   ItemValue{
	       0 {/tile {hextile} store }
	       1 {/tile {halftile} store
		   itemwin items /dimen2slider get reappear}
	       2 {/tile {squaretile} store
		   itemwin items /dimen2slider get disappear}
	   } case
       }
       can 120 10 
       /new CycleItem send 
       10 70 /move 3 index send 
    def

    /tilebutton 
       (Tile) 
       {firsttile {tilemain} {/paintclient tilewin send} ifelse}
       can 50 10
       /new ButtonItem send 
       130 95 /move 3 index send 
    def

    /unitswitch
       (Settings:)
       [(First Unit) (Second Unit)]
       /Right
       {ItemValue
	  [ 0 {/unit2 false store oneify}
	    1 {/unit2 true store twoify}
	  ] case }
       can 60 10
       /new CycleItem send
       300 215 /move 3 index send
    def
/foo{
    /unitcycle
       (Second Unit Placed:)
       [(On Top) (At Corners) (Interleaved)]
 } def
    /secondcycle
       (Second Unit)
        [(Off) (On)]
       /Right
       {ItemValue 0 eq
	   { /ontop false store
	     /unmap win2 send
	    itemwin items /unitswitch get disappear
	      /unit2 false store oneify
	%    items /unitcycle get disappear
	   }
	   {/ontop true store
	       make2win
	    itemwin items /unitswitch get reappear
	%     items /unitcycle get reappear
	   }
       ifelse}
       can 120 10 
       /new CycleItem send
       185 215 /move 3 index send
    def

    /printbutton
       (Print)
       {printwin /FrameCanvas get /Mapped get true eq 
	   {/totop printwin send} 
	   {/totop printwin send /map printwin send} 
	   ifelse
       }
       can 50 10
       /new ButtonItem send
       195 95 /move 3 index send
    def

    /helpbutton
       (Help)
       {first {help} if}
       can 50 10
       /new ButtonItem send
       250 95 /move 3 index send
    def

    /newpartbutton 
       (Draw New Part) 
       {firstdraw {drawnotify} if}
       can 100 10
       /new ButtonItem send 
       10 95 /move 3 index send 
    def

    /dimenslider 
       (Dimension 1:)
       [1 100 25]
       /Right
       {/dimen ItemValue store}
       can 120 10 
       /new SliderItem send 
       10 45 /move 3 index send
    def

    /dimen2slider 
       (Dimension 2:)
       [1 100 25] 
       /Right
       {/dimen2 ItemValue store}
       can 120 10 
       /new SliderItem send 
       10 20 /move 3 index send 
    def
	
    /rotateslider
       (Rotate Unit:)
       [-180 180 0]
       /Right 
       {unit2 { /prerotate2 ItemValue store /paintclient win2 send}
	   { /prerotate ItemValue store /paintclient win send}
	   ifelse}
       can 120 10 
       /new SliderItem send 
       10 130 /move 3 index send 
    def

    /alterrotateslider
       (Alternate Rotation:)
       [-180 180 180]
       /Right 
       {unit2 { /alterrotate2 ItemValue store /paintclient win2 send}
	   { /alterrotate ItemValue store /paintclient win send}
	   ifelse}
       can 120 10 
       /new SliderItem send 
       10 0 /move 3 index send 
    def

    /scaleslider 
       (Scale Unit:) 
       [0 100 1]
       /Right 
       {unit2 {/prescale2 ItemValue store /paintclient win2 send}
	   {/prescale ItemValue store /paintclient win send}
	   ifelse}
       can 120 10 
       /new MySliderItem send 
       250 250 /move 3 index send 
    def
    scaleslider /Round false put
	
dictend def
items /foo undef
items forkitems   
/map win send
win /FrameCanvas get getcanvaslocation 310 sub /move itemwin send
    /map itemwin send
itemwin /ClientCanvas get /Retained false put 
itemwin /FrameCanvas get getcanvaslocation 200 sub /move printwin send
 items begin
     dimen2slider disappear
     alterdocycle  disappear
     unitswitch  disappear
     alterrotateslider disappear
 end
dictend def