diff --git a/exec/load/lightbar.js b/exec/load/lightbar.js new file mode 100644 index 0000000000000000000000000000000000000000..e1a5c392a4d0594de8556a731808ec67d5284d87 --- /dev/null +++ b/exec/load/lightbar.js @@ -0,0 +1,229 @@ +/* + * Generic lightbar interface. + * $Id$ + */ + +//if(SYS_CLOSED==undefined) + load("sbbsdefs.js"); + +/* + * Lightbar function... draws and returns selected value. + * Parameters: + * xpos: Horizontal position of lightbar menu (1-based) + * xpos: Vertical position of lightbar menu (1-based) + * items: an array of objects each having the following properties: + * text - The displayed text. A | prefixes a hotkey + * retval - The value to return if this is selected + * OPTIONAL Properties: + * width - The width of this item. If not specified, is the width of + * the text. Otherwise, the text is truncated or padded with + * spaces to fit the width. + * direction: 0 for vertical, 1 for horizontal. + * Horizontal menus always have one space of padding added between + * items. + * fg: Foreground colour of a non-current item + * bg: Background colour of a non-current item + * hfg: Foreground colour of a current item + * hbg: Background colour of a current item + * kfg: Hotkey forground colour for non-current item + * khfg: Hotkey foreground colour for current item + * current: Index of currently highlighted item (ToDo: This should be passed by reference (how?)!) + * align: If width is greater than the text length, a zero indicates the text + * should be left-aligned, a 1 indicates it should be right-aligned, and + * a 2 indicates it should be centered. + * Return Values: + * null for error, retval from the selected item for non-errors + */ +function lightbar(xpos, ypos, items, direction, fg, bg, hfg, hbg, kfg, khfg, current, align) +{ + var attr=bg<<4|fg; + var cattr=hbg<<4|hfg; + var kattr=bg<<4|kfg; + var kcattr=hbg<<4|khfg; + + if(!(user.settings & USER_ANSI)) { + alert("ANSI not supported for lightbar!"); + return(null); + } + if(!(user.settings & USER_COLOR)) { + alert("Colour not supported for lightbar!"); + return(null); + } + + if(direction < 0 || direction > 1) { + alert("Unknown lightbar direction!"); + return(null); + } + + /* Check that a vertical lightbar fits on the screen */ + if(direction==0 && (ypos+items.length-1 > console.screen_rows)) { + alert("Screen too short for lightbar!"); + return(null); + } + + /* Ensure current is valid */ + if(current<0 || current >= items.length) { + alert("current parameter is out of range!"); + return(null); + } + + /* Check that a horizontal lightbar fits on the screen */ + if(direction==1) { + var end=xpos; + var i; + for(i=0; i<items.length; i++) { + if(items[i].width==undefined) { + if(items[i]==undefined) { + alert("Sparse items array!"); + return(null); + } + if(items[i].text==undefined) { + alert("No text for item "+i+"!"); + return(null); + } + var cleaned=items[i].text; + cleaned=cleaned.replace(/\|/g,''); + end+=cleaned.length+1; + } + else { + end+=items[i].width + } + } + } + + /* Main loop */ + while(1) { + var i; + var j; + + /* Draw items */ + var curx=xpos; + var cury=ypos; + var cursx=xpos; + var cursy=ypos; + for(i=0; i<items.length; i++) { + var width; + var cleaned=items[i].text; + + cleaned=cleaned.replace(/\|/g,''); + width=cleaned.length; + if(items[i]==undefined) { + alert("Sparse items array!"); + return(null); + } + if(items[i].text==undefined) { + alert("No text for item "+i+"!"); + return(null); + } + if(items[i].width!=undefined) + width=items[i].width; + console.gotoxy(curx, cury); + if(i==current) { + cursx=curx; + cursy=cury; + } + j=0; + if(cleaned.length < width) { + if(align==1) { + if(current==i) + console.attributes=cattr; + else + console.attributes=attr; + for(;j<width-cleaned.length;j++) + console.write(' '); + } + if(align==2) { + if(current==i) + console.attributes=cattr; + else + console.attributes=attr; + for(;j<(width-cleaned.length)/2;j++) + console.write(' '); + } + } + for(; j<items[i].text.length; j++) { + if(width > -1 && j > width) + break; + if(items[i].text.substr(j,1)=='|') { + if(current==i) + console.attributes=kcattr; + else + console.attributes=kattr; + } + else { + if(current==i) + console.attributes=cattr; + else + console.attributes=attr; + console.write(items[i].text.substr(j,1)); + } + } + if(current==i) + console.attributes=cattr; + else + console.attributes=attr; + while(j<width) { + console.write(" "); + j++; + } + if(direction==0) + cury++; + else + curx+=width+1; + } + console.gotoxy(cursx,cursy); + + /* Get input */ + var key=console.getkey(K_UPPER); + switch(key) { + case KEY_UP: + if(direction==0) { + if(current==0) + current=items.length; + current--; + } + break; + case KEY_DOWN: + if(direction==0) { + current++; + if(current==items.length) + current=0; + } + break; + case KEY_LEFT: + if(direction==1) { + if(current==0) + current=items.length; + current--; + } + break; + case KEY_RIGHT: + if(direction==1) { + current++; + if(current==items.length) + current=0; + } + break; + case KEY_HOME: + current=0; + break; + case KEY_END: + current=items.length-1; + break; + case '\r': + case '\n': + if(items[current].retval==undefined) + return(undefined); + return(items[current].retval); + break; + default: + for(i=0; i<items.length; i++) { + if(items[i].text.indexOf('|'+key)!=-1) { + current=i; + break; + } + } + break; + } + } +}