diff options
Diffstat (limited to 'xmenu.inc')
-rw-r--r-- | xmenu.inc | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/xmenu.inc b/xmenu.inc new file mode 100644 index 0000000..bc9680e --- /dev/null +++ b/xmenu.inc @@ -0,0 +1,381 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% List dialog handling. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Some global vars. +% +/xmenu.vspace.default { xmenu .xm_list get length 15 ge { 2 } { 4 } ifelse } def +/xmenu.hspace 12 def +/xmenu.light white def +/xmenu.dark black def +/xmenu.font font.normal def +/xmenu.normal.bg lightgray def +/xmenu.normal.fg black def +/xmenu.selected.fg white def +/xmenu.selected.bg 0x6c6c6c newcolor + +small_layout { + /xmenu.maxlines 22 def +} { + /xmenu.maxlines 24 def +} ifelse + +% xmenu layout +% +% [ selected_entry string_list x y panel_x ] +% +/.xm_current 0 def % selected entry +/.xm_list 1 def % string list +/.xm_x 2 def % menu x pos +/.xm_y 3 def % menu y pos +/.xm_width 4 def % menu width +/.xm_height 5 def % menu height +/.xm_panel_x 6 def % panel entry x pos +/.xm_panel_width 7 def % panel entry width +/.xm_panel_height 8 def % panel entry height +/.xm_vspace 9 def % vspace per menu +/.xm_title 10 def % xmenu title +/.xm_size 11 def % xmenu size + + +% short hands +/xmenu.x { xmenu .xm_x get } def +/xmenu.y { xmenu .xm_y get } def +/xmenu.width { xmenu .xm_width get } def +/xmenu.height { xmenu .xm_height get } def + +/xmenu.vspace { xmenu .xm_vspace get dup .undef ne { } { pop xmenu.vspace.default } ifelse } def + +/xmenu.saved { xmenu.saved.areas xmenu.column get 2 get } def + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Create new xmenu. +% +% ( ) ==> ( window ) +% +/window.xmenu { + widget.size array + dup .type t_xmenu put +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Handle keyboad input. +% +% ( key_in ) ==> ( key_out ) +% +/xmenu.input { + dup 0 eq { return } if + + dup keyEsc eq { + xmenu 0 xmenu.oldentry put + window.done + pop 0 + } if + + dup keyEnter eq { + window.current .xmenu.update get + window.done + exec + pop 0 + } if + + dup keyDown eq { + xmenu .xm_current get 1 add xmenu.select + pop 0 + } if + + dup keyUp eq { + xmenu .xm_current get 1 sub xmenu.select + pop 0 + } if + + dup keyPgDown eq { + xmenu .xm_current get 5 add + xmenu .xm_list get length 1 sub min xmenu.select + pop 0 + } if + + dup keyPgUp eq { + xmenu .xm_current get 5 sub + 0 max xmenu.select + pop 0 + } if + + dup keyHome eq { + 0 xmenu.select + pop 0 + } if + + dup keyEnd eq { + xmenu .xm_list get length 1 sub xmenu.select + pop 0 + } if + + dup keyRight eq { + xmenu .xm_current get + dup xmenu.maxlines div 1 add xmenu.columns mod xmenu.maxlines mul + exch xmenu.maxlines mod add + xmenu .xm_list get length 1 sub min xmenu.select + pop 0 + } if + + dup keyLeft eq { + xmenu .xm_current get + dup xmenu.maxlines div xmenu.columns add 1 sub xmenu.columns mod xmenu.maxlines mul + exch xmenu.maxlines mod add + xmenu .xm_list get length 1 sub min xmenu.select + pop 0 + } if + + dup keyF1 eq { + show_help + pop 0 + } if + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Calculate menu sizes. +% +% ( ) ==> ( ) +% +/xmenu.sizes { + /xmenu.lheight xmenu.font setfont fontheight xmenu.vspace dup add add def + + /xmenu.columns xmenu .xm_list get length xmenu.maxlines add 1 sub xmenu.maxlines div def + + /xmenu.lastheight + xmenu .xm_list get length xmenu.maxlines xmenu.columns 1 sub mul sub xmenu.lheight mul + def + + xmenu .xm_height + xmenu .xm_list get length xmenu.maxlines min xmenu.lheight mul + put + + xmenu .xm_width + 0 xmenu .xm_list get { exec strsize pop max } forall xmenu.hspace 2 mul add + put + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Init and show menu. +% +% ( window ) ==> ( ) +% +% xmenu: [ selected_entry [ text0 text1 ... ] x y ] +% +/xmenu.init { + /xmenu over .xmenu get def + + xmenu.sizes + + dup .saved.areas xmenu.columns array /xmenu.saved.areas over def put + + 0 1 xmenu.columns 1 sub { + /xmenu.column exch def + + dup .saved.areas get xmenu.column + + [ + xmenu.column xmenu.width 2 add mul xmenu.x add 1 sub xmenu.y 1 sub moveto + currentpoint + + xmenu.light xmenu.dark + xmenu.width 2 add + xmenu.column 1 add xmenu.columns eq { xmenu.lastheight } { xmenu.height } ifelse 2 add + over over savescreen 5 1 roll + drawborder + + ] put + + } for + + 0 1 xmenu .xm_list get length 1 sub { xmenu.viewentry } for + + /xmenu.oldentry xmenu .xm_current get def + + dup .x xmenu.x put + .y xmenu.y put + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Close menu. +% +% ( ) ==> ( ) +% +/xmenu.done { + /xmenu.tmpbuf xmenu.tmpbuf free .undef def + /xmenu.saved.normal xmenu.saved.normal free .undef def + /xmenu.saved.selected xmenu.saved.selected free .undef def + /xmenu.saved.areas .undef def +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Draw xmenu. +% +% ( window ) ==> ( ) +% +/xmenu.show { + window.push +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Draw single entry. +% +% ( entry ) ==> ( ) +% +/xmenu.viewentry { + xmenu.font setfont + + dup xmenu.maxlines mod xmenu.lheight mul xmenu.y add /xmenu.pos.y exch def + + dup xmenu.maxlines div /xmenu.column over def + xmenu.width 2 add mul xmenu.x add /xmenu.pos.x exch def + + xmenu.pos.x xmenu.pos.y moveto + + dup xmenu .xm_current get eq { xmenu.saved.selected } { xmenu.saved.normal } ifelse + + dup { + transp { pop } { restorescreen } ifelse + } { + pop + + dup xmenu .xm_current get eq { xmenu.selected.bg } { xmenu.normal.bg } ifelse + setcolor xmenu.width xmenu.lheight fillrect + + dup xmenu .xm_current get eq { + xmenu.pos.x xmenu.pos.y moveto + xmenu.dark xmenu.light xmenu.width xmenu.lheight drawborder + } if + + dup xmenu .xm_current get eq { /xmenu.saved.selected } { /xmenu.saved.normal } ifelse + xmenu.pos.x xmenu.pos.y moveto + xmenu.width xmenu.lheight + savescreen + def + } ifelse + + + transp { + % copy entry to avoid reading the screen again + dup xmenu .xm_current get eq { xmenu.saved.selected } { xmenu.saved.normal } ifelse + xmenu.tmpbuf .undef eq { + dup length malloc /xmenu.tmpbuf exch def + } if + xmenu.tmpbuf exch dup length memcpy + + 0 xmenu.pos.y xmenu.y sub moveto 1 1 rmoveto + xmenu.saved transp xmenu.tmpbuf blend + + xmenu.pos.x xmenu.pos.y moveto xmenu.tmpbuf restorescreen + } if + + dup xmenu .xm_current get eq { xmenu.selected.fg } { xmenu.normal.fg } ifelse setcolor + xmenu.pos.x xmenu.hspace add xmenu.pos.y xmenu.vspace add moveto + xmenu .xm_list get over get exec show + + pop + + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Select menu entry. +% +% ( new_entry ) ==> ( ) +% +/xmenu.select { + dup 0 lt { xmenu .xm_list get length add } if + dup xmenu .xm_list get length ge { xmenu .xm_list get length sub } if + + xmenu .xm_current get over xmenu .xm_current rot put + xmenu.viewentry + xmenu.viewentry +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Panel/xmenu helper function. +% +% ( ) => ( ) +% +/pmenu.panel.update { + panel.text.moveto + + xmenu .xm_panel_x currentpoint pop xmenu.hspace sub put + xmenu .xm_x xmenu .xm_panel_x get put + + pmenu.update +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Panel/xmenu helper function. +% +% ( ) => ( width ) +% +/pmenu.width { + % Use this instead of the line below and remove the actRedrawPanel + % things if you want fixed size panel entries. + + % xmenu .xm_panel_width get xmenu.hspace 2 mul sub + + xmenu .xm_title get dup .undef eq { + pop xmenu .xm_list get xmenu .xm_current get get + } if + exec strsize pop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Panel/xmenu helper function. +% +% ( ) => ( ) +% +/pmenu.update { + xmenu .xm_panel_x get xmenu.hspace add panel.text.y moveto + +% currently not needed - we're redrawing the whole panel anyway +% xmenu .xm_panel_width get xmenu.hspace sub xmenu .xm_panel_height get +% panel.bg setcolor fillrect + + panel.normal setcolor + panel.font setfont + xmenu .xm_panel_x get xmenu.hspace add + panel.text.y + moveto + xmenu .xm_title get dup .undef eq { + pop xmenu .xm_list get xmenu .xm_current get get + } if + exec show +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Panel/xmenu helper function. +% +% ( ) => ( ) +% +/pmenu.init { + xmenu.sizes + + xmenu .xm_y panel.text.y 1 sub xmenu.height sub put + xmenu .xm_panel_width xmenu.width put + xmenu .xm_panel_height fontheight put +} def + + |