/object superclass /w 0 def %begin postscript section /w persist %end postscript section /h 0 def %begin postscript section /h persist %end postscript section %begin postscript section /mx persist %end postscript section /mx { % -- matrixtype matrix } def /x { % -- float mx 4 get } def /y { % -- float mx 5 get } def /addmember { % drawable -- dup /visible false put //addmember exec invalidate } def /removemember { % drawable -- dup /onclose exch send //removemember exec invalidate } def /gs null def /gstart nullproc def /gstop { % -- /gs unpromote } def /greset { % -- members { /greset exch send } forall gstop } def /gset { % -- mx concat path clip newpath } def /ginit { % -- visible { gs null ne { gs setstate } { /ginit @parent send gset currentstate /gs exch promote } ifelse } { /ginit @parent send gset } ifelse } def /gexec { % name -- visible {validated} false ifelse { gsave ginit [exch cvx exec] pop grestore } {pop} ifelse } def /gexeca { % name any * -- visible {validated} false ifelse { gsave ginit [3 1 roll aload length 1 add -1 roll cvx exec] pop grestore } { pop pop } ifelse } def /gfix { % name -- visible {validated} false ifelse { gsave ginit clipcanvaspath clip clippath emptypath not { newpath [exch cvx exec] } if pop grestore } {pop} ifelse } def /slaves //nullarray def /addslave { % drawable -- dup /@owner self soften put slaves [2 index] append /slaves exch promote dup initmember visible { /owner_open exch send } {pop} ifelse } def /removeslave { % drawable -- slaves 1 index arrayindex not -1 if dup 0 lt { pop pop } { visible { /owner_close 2 index send } if exch /@owner null put slaves dup length array copy exch arraydelete /slaves exch promote } ifelse } def /delslave { % drawable -- dup removeslave /destroy exch send } def /owner_open { % -- map } def /owner_close { % -- unmap } def /destroy { % -- @owner null ne { self /delslave @owner send } if slaves { dup /@owner null put /destroy exch send } forall //destroy exec } def /mapped { % -- boolean /visible promoted not } def /map { % -- mapped not { /visible unpromote onopen damage } if } def /unmap { % -- mapped { damage onclose /visible false promote } if } def /OnOpen nullproc def /OnClose nullproc def /onopen { % -- visible { validate gstart /OnOpen load nullproc ne { //nullarray /OnOpen self Send } if members { /onopen exch send } forall slaves { /owner_open exch send } forall } if } def /onclose { % -- visible { slaves { /owner_close exch send } forall members { /onclose exch send } forall /OnClose load nullproc ne { //nullarray /OnClose self Send } if gstop } if } def /setscript { % string string -- boolean onclose //setscript exec onopen } def /Paint { % -- path BG setcolor fill } def /path { % -- 0 0 w h rectpath } def /paintall { % -- //nullarray /Paint self Send members { /paint exch send } forall } def /paint { % -- /paintall gexec } def /fixall { % -- //nullarray /Paint self Send members { /fix exch send } forall } def /fix { % -- /fixall gfix } def /damageall { % -- clippath extenddamage } def /damage { % -- /damageall gexec } def /fixedwidth false def /fixedheight false def /minwidth 0 def /minheight 0 def /preferredwidth 0 def /preferredheight 0 def /preferredshape { % -- x y w h reshape } def /bounds { % -- rectangle [x y w h] } def /move { % float float -- x 2 index ne true { y 1 index ne } ifelse { damage /mx mx 4 -2 roll mtranslate softpromote @parent dup null ne { /invalidate exch send } {pop} ifelse greset damage } { pop pop } ifelse } def /rmove { % float float -- x 3 -1 roll add y 3 -1 roll add move } def /reshape { % float float float float -- minwidth fixedwidth { 3 -1 roll pop preferredwidth } {3 -1 roll} ifelse max exch minheight fixedheight { exch pop preferredheight } {exch} ifelse max w 2 index eq { h 1 index eq } false ifelse { pop pop move } { damage /h exch softpromote /w exch softpromote /mx mx 4 -2 roll mtranslate softpromote greset damage @parent dup null ne { /invalidate exch send } {pop} ifelse invalidate } ifelse } def /invalid false def /Validate nullproc def /validate { % -- invalid {visible} false ifelse { placement /Validate load nullproc ne { //nullarray /Validate self Send } if damage } if } def /invalidate { % -- invalid not { /invalid true promote visible {validate} if } if } def %begin postscript section /justification persist %end postscript section /posE 10000 def %begin postscript section /posE persist %end postscript section /posW 10000 def %begin postscript section /posW persist %end postscript section /posN 10000 def %begin postscript section /posN persist %end postscript section /posS 10000 def %begin postscript section /posS persist %end postscript section /Position { % float float float float -- reshape } def /position { % float float -- x y minwidth fixedwidth {preferredwidth} {w } ifelse max minheight fixedheight { preferredheight} {h} ifelse max posW 10000 lt { 4 -1 roll pop posW 4 1 roll posE 10000 lt { fixedwidth { 4 -1 roll pop 5 -1 roll 2 index sub 2 div 4 1 roll } { exch pop 5 -1 roll 3 index sub posE sub exch } ifelse } { 6 -1 roll pop } } { posE 10000 lt { 4 -1 roll pop 5 -1 roll 2 index sub posE sub 4 1 roll } { 6 -1 roll pop } } ifelse ifelse posS 10000 lt { 3 -1 roll pop posS 3 1 roll posN 10000 lt { fixedheight { 3 -1 roll pop 4 -1 roll 1 index sub 2 div 3 1 roll } { pop 4 -1 roll 2 index sub posN sub } ifelse } { 5 -1 roll pop } } { posN 10000 lt { 3 -1 roll pop 4 -1 roll 1 index sub posN sub 3 1 roll } { 5 -1 roll pop } } ifelse ifelse [5 -4 roll] /Position self Send } def /setposition { % any any any any -- 3 index null ne {4 -1 roll} { 4 -1 roll pop 10000 } ifelse 4 1 roll 2 index null ne {3 -1 roll} { 3 -1 roll pop 10000 } ifelse 3 1 roll 1 index null ne {exch} { exch pop 10000 } ifelse exch dup null eq { pop 10000 } if 3 index posW ne true { 2 index posS ne } ifelse true { 1 index posE ne } ifelse true { dup posN ne } ifelse { /posW 5 -1 roll softpromote /posS 4 -1 roll softpromote /posE 3 -1 roll softpromote /posN exch softpromote @parent dup null ne { /invalidate exch send } {pop} ifelse } { pop pop pop pop } ifelse } def /placemode /position def %begin postscript section /placemode persist %end postscript section /place_h 10 def %begin postscript section /place_h persist %end postscript section /place_v 10 def %begin postscript section /place_v persist %end postscript section /Placement { % name -- pop members { w h /position 4 -1 roll send } forall } def /placement_left2right { % -- members length members { /preferredshape exch send } forall h exch 0 exch { 2 copy ge { pop pop pop exit } if w /w members 4 index get send sub 4 1 roll /h members 3 index get send 4 1 roll 1 index 1 add exch { 5 index 0 gt { 2 copy lt } false ifelse not {exit} if /w members 3 index get send place_h add 6 index gt {exit} if 6 -1 roll /w members 4 index get send neg place_h sub add 6 1 roll 5 -1 roll /h members 5 -1 roll dup 1 add 6 1 roll get send max 5 1 roll } loop justification placement_left2right$SwiTch0 exch 2 copy known not { pop /$deFaUlT } if get exec 4 -1 roll 6 -1 roll neg add 4 1 roll { 2 index 2 index ge { exch pop 4 -1 roll pop exit } if 4 index 4 index /move members 6 index get send 5 -1 roll /w members 5 index get send place_h add add 5 1 roll 3 -1 roll 1 add 3 1 roll } loop 3 -1 roll place_v neg add 3 1 roll } loop } def /placement_left2right$SwiTch0 3 dict dup begin /$deFaUlT { 6 -1 roll pop 0 5 1 roll } def /Right { 6 -1 roll 5 1 roll } def /Centered { 6 -1 roll 2 div 5 1 roll } def end def /placement_top2bottom { % -- members length members { /preferredshape exch send } forall 0 exch 0 exch { 2 copy ge { pop pop pop exit } if h /h members 4 index get send sub 4 1 roll /w members 3 index get send 5 1 roll 1 index 1 add exch { 4 index 0 gt { 2 copy lt } false ifelse not { 5 -1 roll pop exit } if /h members 3 index get send place_v add 5 index gt { 5 -1 roll pop exit } if 5 -1 roll /h members 4 index get send neg place_v sub add 5 1 roll 6 -1 roll /w members 5 -1 roll dup 1 add 6 1 roll get send max 6 1 roll } loop h 4 1 roll { 2 index 2 index ge { exch pop 3 -1 roll pop exit } if 4 -1 roll /h members 5 index get send neg add 4 1 roll justification placement_top2bottom$SwiTch1 exch 2 copy known not { pop /$deFaUlT } if get exec 3 -1 roll 1 add 3 1 roll 4 -1 roll place_v neg add 4 1 roll } loop 3 -1 roll place_h 5 -1 roll add add 3 1 roll } loop } def /placement_top2bottom$SwiTch1 3 dict dup begin /$deFaUlT { 4 index 4 index /move members 6 index get send } def /Right { 4 index 6 index add /w members 5 index get send sub 4 index /move members 6 index get send } def /Centered { 4 index 6 index /w members 6 index get send sub 2 div add 4 index /move members 6 index get send } def end def /placement { % -- /validated false promote placemode placement$SwiTch2 exch 2 copy known not { pop /$deFaUlT } if get exec /validated unpromote /invalid unpromote } def /placement$SwiTch2 5 dict dup begin /$deFaUlT { [placemode] /Placement self Send } def /position { members { w h /position 4 -1 roll send } forall } def /none {} def /top2bottom {placement_top2bottom} def /left2right {placement_left2right} def end def /setplacement { % name -- dup placemode ne { /placemode exch softpromote invalidate } {pop} ifelse } def /setjustification { % name -- dup justification ne { /justification exch softpromote invalidate } {pop} ifelse } def /OnMenu { % -- @menu null ne { self /showmenu @menu send } if } def /onmenu { % -- visible { @menu null ne } false ifelse { /OnMenu gexec } { /onmenu @parent send } ifelse } def /OnSelect nullproc def /OnAdjust nullproc def /onselect { % -- /OnSelect gexec } def /onadjust { % -- /OnAdjust gexec } def /inpath { % eventtype -- boolean gsave ginit path dup /XLocation get exch /YLocation get pointinpath grestore } def /hit { % eventtype -- drawable visible { dup inpath } false ifelse { members length 1 sub { dup 0 lt { pop pop self exit } if 1 index /hit members 3 index get send dup 3 1 roll null ne { pop exch pop exit } if exch pop 1 sub } loop } { pop null } ifelse } def /hitlist { % eventtype -- drawable * //nullarray members { 2 index /inpath 2 index send { exch [3 -1 roll] append } {pop} ifelse } forall exch pop } def /recthitlist { % rectangle -- drawable * //nullarray members { 2 index /bounds 2 index send rectinrect { exch [3 -1 roll] append } {pop} ifelse } forall exch pop } def /focus_state { % -- nametype self @focus eq { cv currentinputfocus eq /active /inactive ifelse } /none ifelse } def /request_focus { % -- self @focus ne { [self] /set_focus @window Send } if } def /focus_change nullproc def /edit_sel //nullarray def /grid 5 def /edit_mode { % -- boolean @window /edit_mode known { @window /edit_mode get } false ifelse } def /edit_ctx_dragable { % -- boolean /placemode @edit_ctx send /position eq } def /@edit_ctx { % -- drawable @current_layout /edit_ctx known { @current_layout /edit_ctx get null ne { @current_layout /edit_ctx get } {@window_layout} ifelse } {@current_layout} ifelse } def /edit_rmove { % float float -- posW 10000 lt { posW 2 index add /posW exch promote } if posE 10000 lt { posE 2 index neg add /posE exch promote } if posS 10000 lt { posS 1 index add /posS exch promote } if posN 10000 lt { posN 1 index neg add /posN exch promote } if rmove } def /edit_reshape { % float float float float -- exch minwidth max exch minheight max fixedwidth { preferredwidth 0 ne } false ifelse { exch pop preferredwidth exch } if fixedheight { preferredheight 0 ne } false ifelse { pop preferredheight } if posW 10000 lt { posW 4 index x sub add /posW exch promote } if posE 10000 lt { posE 4 index neg 3 index sub x add w add add /posE exch promote } if posS 10000 lt { posS 3 index y sub add /posS exch promote } if posN 10000 lt { posN 3 index neg 2 index sub y add h add add /posN exch promote } if reshape } def /xor_mode { % colortype -- matrix currentmatrix cv setcanvas setmatrix BG exch setxorop } def /paint_selected { % -- gsave mx concat editSELcolor xor_mode gsave -1 [0 0 w h] insetstroke aload pop rectpath edit_ctx_dragable not { [6 6] 0 setdash } if stroke grestore @parent /edit_sel known { @parent /edit_sel get } {edit_sel} ifelse length 1 le { fixedwidth not { -5 h 2 div 2 sub 5 5 rectpath w h 2 div 2 sub 5 5 rectpath } if fixedheight not { w 2 div 2 sub -5 5 5 rectpath w 2 div 2 sub h 5 5 rectpath } if fixedwidth not { fixedheight not } false ifelse { -5 -5 5 5 rectpath w -5 5 5 rectpath w h 5 5 rectpath -5 h 5 5 rectpath } if fill } if grestore } def /paint_edit_sel { % -- edit_sel { /paint_selected exch send } forall } def /paint_edit_mode { % -- editCTXcolor xor_mode -1 [0 0 w h] insetstroke aload pop rectpath -2 [0 0 w h] insetstroke aload pop rectpath stroke paint_edit_sel } def /set_edit_sel { % drawable * -- /paint_edit_sel gexec /edit_sel exch promote /paint_edit_sel gexec } def /start_edit_ctx { % -- map /paint_edit_mode gexec } def /stop_edit_ctx { % -- /paint_edit_mode gexec /edit_sel unpromote } def /edit_ctx_parent { % -- [@parent] /set_edit_ctx @window Send [[ self]] /set_edit_sel @edit_ctx Send } def /edit_ctx_selected { % -- edit_sel length 1 eq { [edit_sel 0 get] /set_edit_ctx @window Send } if } def /edit_rubber_rect_track { % -- stroke mouseevent /XLocation get mouseevent /YLocation get trackx tracky points2rect rectpath gsave stroke grestore } def /edit_rubber_rect { % -- rectangle editSELcolor xor_mode mouseevent /XLocation get mouseevent /YLocation get 0 0 rectpath gsave stroke grestore /edit_rubber_rect_track track pop stroke mouseevent /XLocation get mouseevent /YLocation get trackx tracky points2rect 4 array astore } def /edit_select_from_rect { % -- //nullarray set_edit_sel edit_rubber_rect recthitlist set_edit_sel } def /dragx 0 def /dragy 0 def /edit_drag_sel_track { % -- trackdx trackdx cvi grid mod sub trackdy trackdy cvi grid mod sub dragx 2 index ne true { dragy 1 index ne } ifelse { paint_edit_sel grestore gsave exch dup /dragx exch promote exch dup /dragy exch promote translate paint_edit_sel } { pop pop } ifelse } def /edit_drag_sel { % -- edit_ctx_dragable { gsave /edit_drag_sel_track track pop grestore edit_sel { dragx dragy /edit_rmove 4 -1 roll send } forall /dragx unpromote /dragy unpromote } if } def /which_reshape_handle { % float float -- name 1 index w sub 2 sub abs 5 lt { fixedwidth not } false ifelse { exch pop dup h neg 2 div add abs 5 lt { pop /West } { fixedheight not { dup 3 add abs 5 lt { pop /SouthWest } { h sub 2 sub abs 5 lt /NorthWest null ifelse } ifelse } { pop null } ifelse } } { 1 index 3 add abs 5 lt { fixedwidth not } false ifelse { exch pop dup h neg 2 div add abs 5 lt { pop /East } { fixedheight not { dup 3 add abs 5 lt { pop /SouthEast } { h sub 2 sub abs 5 lt /NorthEast null ifelse } ifelse } { pop null } ifelse } } { exch w neg 2 div add abs 5 lt { fixedheight not } false ifelse { dup 3 add abs 5 lt { pop /South } { h sub 2 sub abs 5 lt /North null ifelse } ifelse } { pop null } } ifelse } ifelse ifelse } def /seltrackr [0 0 0 0] def /seltrackX 0 def /seltrackY 0 def /seltrackW true def /seltrackH true def /seltrackrect { % float float -- rectangle exch dup cvi grid mod sub exch dup cvi grid mod sub seltrackW { 1 index seltrackX sub abs minwidth lt } false ifelse { seltrackX 3 -1 roll seltrackX lt { minwidth neg } {minwidth} ifelse add exch } if seltrackH { dup seltrackY sub abs minheight lt } false ifelse { seltrackY exch seltrackY lt { minheight neg } {minheight} ifelse add } if seltrackX seltrackY points2rect 4 array astore seltrackW not { dup 0 0 put dup 2 w put } if seltrackH not { dup 1 0 put dup 3 h put } if } def /seltrack { % -- trackx tracky seltrackrect seltrackr cmp not { stroke -1 trackx tracky seltrackrect dup /seltrackr exch promote insetstroke aload pop rectpath gsave stroke grestore } if } def /edit_reshape_handle { % -- boolean gsave mx concat mouseevent /XLocation get mouseevent /YLocation get grestore which_reshape_handle dup null ne { edit_reshape_handle$SwiTch3 exch 2 copy known { get exec } { pop pop } ifelse paint_selected gsave mx concat editSELcolor xor_mode seltrackr aload pop rectpath /seltrack track pop stroke grestore x seltrackr 0 get add y seltrackr 1 get add seltrackr 2 get seltrackr 3 get edit_reshape paint_selected /seltrackr unpromote /seltrackX unpromote /seltrackY unpromote /seltrackW unpromote /seltrackH unpromote true } { pop false } ifelse } def /edit_reshape_handle$SwiTch3 8 dict dup begin /NorthEast { w /seltrackX exch promote } def /SouthEast { h /seltrackY exch promote edit_reshape_handle$SwiTch3 /NorthEast get exec } def /NorthWest {} def /SouthWest { h /seltrackY exch promote edit_reshape_handle$SwiTch3 /NorthWest get exec } def /North { /seltrackW false promote } def /South { h /seltrackY exch promote edit_reshape_handle$SwiTch3 /North get exec } def /West { /seltrackH false promote } def /East { w /seltrackX exch promote edit_reshape_handle$SwiTch3 /West get exec } def end def /in_sel_path { % eventtype -- boolean true edit_sel { exch 2 index /inpath 4 -1 roll send { exch pop true exch not exit } if } forall { pop false } if } def /edit_select_click { % -- edit_sel length 1 eq { /edit_reshape_handle edit_sel 0 get send } false ifelse not { mouseevent in_sel_path { track_state edit_select_click$SwiTch4 exch 2 copy known { get exec } { pop pop } } { track_state edit_select_click$SwiTch5 exch 2 copy known { get exec } { pop pop } } ifelse ifelse } if } def /edit_select_click$SwiTch4 2 dict dup begin /mouse_click { mouseevent hitlist edit_sel length 1 gt { dup length 0 ne { 0 1 getinterval } if } { dup edit_sel 0 get arrayindex not -1 if dup 0 lt { pop pop //nullarray } { 1 index exch 1 add 3 -1 roll length mod 1 getinterval } ifelse } ifelse set_edit_sel } def /mouse_drag {edit_drag_sel} def end def /edit_select_click$SwiTch5 2 dict dup begin /mouse_click { mouseevent hitlist dup length 0 ne { 0 1 getinterval } if set_edit_sel } def /mouse_drag {edit_select_from_rect} def end def