program XTRA4,2.0(107) ! Two XTREEs (shopping cart app) !-------------------------------------------------------------------- ! XTRA4.BP - Dueling XTREE controls ! ! Demonstrate/test simple use of two XTREE controls at the same ! time, allowing items to be transferred from one to another ! using various techniques. ! ! NOTES ! The transfer between the two trees is similar to what you might ! use in a "shopping cart" application. It is not symmetrical. ! Items are not removed from the first tree when copied into the ! second. (The first tree is more like a menu or catalog, rather ! than a representation of inventory which would be reduced each ! time an item was put in a cart.) The reverse operation ! (removing items from the "cart") simply consistes of deleting ! them from tree2. ! ! The "Add to Cart" operation can be triggered in multiple ways: ! - Select item(s) and click "Add to Cart" ! - Double-click an item (single select) ! - Select item(s) and hit ENTER ! - Select item(s) and drag it(them) to card ! ! The drag/drop option is new in 5.1.1203.0 !-------------------------------------------------------------------- ! EDIT HISTORY ![100] September 6, 2004 09:22 PM Edited by Jack ! Created from XTRARY to test multiple XTREE controls ![101] October 16, 2004 04:38 PM Edited by Jack ! Add logic to delete item(s) from 2nd list; misc improvements ![102] March 15, 2005 11:15 AM Edited by joaquin ! REQUIRES 923+!!! ! Support logic for better direct access the appropriate row ! when clicking on an inactive xtree. (Previously, the click ! location in this case was lost; as of 923 xtree remembers the ! inactive click row, but we have to clear ANSWER when re-activating ! the xtree in order to have it use the previously clicked row. ! Otherwise the contents of ANSWER still overrides the click.) ! Also update to use new symbols; use new VK_xrF### virtual key ! syntax to support a right-click action on the add & remove ! buttons; use SCRSTS to output status information ![103] July 18, 2006 08:03 AM Edited by joaquin ! Minor source cleanup; add MBF_SYSMENU to SCRSTS (so it ! gets a minimize button) (requires SCRSTS.SBX edit 105+) !VERSION 2.0 - ![104] January 26, 2011 10:08 PM Edited by jack ! Rewrite program to modernize it and add drag/drop; remove ! the special evtmsg/scrsts stuff (just use debug msg window) ![105] February 4, 2011 02:22 PM Edited by jack ! Test 5.1.1205 using alphanumeric EVENTWAIT control ids ! Also, fix misc GUI bugs relating to controls being created ! out of order and handling EXITCODE 1 on exit ![106] February 08, 2011 10:29 AM Edited by jack ! Revise logic to do away with XTROP_DELSEL (which isn't really ! appropriate for a shopping cart) and just use XTROP_REPLACE ! to update the cart after deletions. !-------------------------------------------------------------------- ++pragma ERROR_IF_NOT_MAPPED "ON" ! (avoid stupid unmapped symbol errors) ++include ashinc:xtree.map ++include ashinc:xtree.def ! [103] ++include ashinc:xtree.sdf ! [104] ++include ashinc:ashell.def define MAX_ITEMS = 100 define ITEM_LEN = 68 ! [104] length of each item DEFSTRUCT ST_ITEMREC ! [104] structured layout of each item map2 REGION,S,11 map2 WINE,S,45 map2 VINTAGE,S,4 map2 PRICE,S,8 ENDSTRUCT map1 SHOP'PARAMS ! [104] TREE1 is the "shop" (all avail items) map2 SHOP'XTR,XTRCTL map2 SHOP'XFLG,ST_XFLAGS map2 SHOP'ITEMS,F map2 SHOP'XSROW,B,2 map2 SHOP'XSCOL,B,2 map2 SHOP'XEROW,B,2 map2 SHOP'XECOL,B,2 map2 SHOP'ARRAY(MAX_ITEMS),S,ITEM_LEN map2 SHOP'ANSWERX map3 SHOP'ANSARY(MAX_ITEMS) map4 SHOP'MSEL,S,1 ! (multi-selection) map2 SHOP'ANSWER$,S,MAX_ITEMS,@SHOP'ANSWERX map1 CART'PARAMS ! [104] TREE2 is the "cart" (selected items) map2 CART'XTR,XTRCTL map2 CART'XFLG,ST_XFLAGS map2 CART'ITEMS,F ! # items in tree map2 ADDCOUNT,F ! # items being appended map2 CART'XSROW,B,2 map2 CART'XSCOL,B,2 map2 CART'XEROW,B,2 map2 CART'XECOL,B,2 map2 CART'ARRAYX ! [106] (make it easy to copy entire array) map3 CART'ARRAY(MAX_ITEMS),S,ITEM_LEN map2 CART'ANSWERX map3 CART'ANSARY(MAX_ITEMS) map4 CART'MSEL,S,1 ! (multi-selection) map2 CART'ANSWER$,S,MAX_ITEMS,@CART'ANSWERX map2 TEMP'ARRAYX ! [106] used during deletion/scrunch map3 TEMP'ARRAY(MAX_ITEMS),S,ITEM_LEN ! [106] map1 COLDEF1$,S,0 map1 COLDEF2$,S,0 map1 MISC map2 CNO,F map2 COPYID,B,2 ! COPY > button id map2 COPYID$,S,24,"btnCopy" ! [105] alphanumeric id map2 DELID,B,2 ! DEL button id map2 DELID$,S,24,"btnDel" ! [105] alphanumeric id map2 GRPID,B,2 map2 GRPID$,S,24,"grpButtons" ! [105] (alphanumeric id) map2 STATUS,F map2 A,B,1 map2 I,F map2 J,F map2 EXITCODE,F map2 TOTAL,F map2 DELCNT,I,2 ! [106] map2 ITEMREC,ST_ITEMREC map1 EVENTWAIT'PARAMS ! [102] map2 EVW'FLAGS,B,4 map2 EVW'GRPID,B,2 map2 EVW'CTLID,B,2 map2 EVW'CTLID$,S,24 ! [105] map2 EVW'GRPID$,S,24 ! [105] ! sample array data ! 12345678901234567890123456789012345678901234567890 ! first line contains our titles... (no longer used directly) !data "Zip City State Country" ! 1234567890123456789012345678901234567890123456578901234567890123456789 data "California Joesph Phelps 'Insignia' Napa Valley 1998 899.99" data "California Ridge Vineyards Santa Cruz Mountains Red 2007 29.99" data "Oregon Elk Cove 'Reserve' Willamette Pinot Noir 2008 89.99" data "France Domaine la Garrigue 'Cuvée Romaine' 2009 11.99" data "France Roger Sabon 'Les Olivets' 2006 24.99" data "France Beauregard Ducasse Rouge, Graves 2001 12.99" data "France Domaine de la Romanee-Conti Richebourg 1969 899.99" data "France Malescot-St-Exupéry 2009 119.99" data "France Veuve Clicquot Brut 39.99" data "France Moet & Chandon 'Dom Pérignon' Brut 2002 139.99" data "France Bouchard Pere et Fils Chevalier-Montrachet 2007 259.99" data "France Nicolas Potel Grands Echezeaux Grand Cru 2006 169.95" data "Portugal Quito do Crasto Reserva Vinhas Velhas 2005 35.99" data "Portugal Niepoort Charme 2006 93.23" data "Portugal Casa Ferreirinha 'Esteva' Douro 2008 11.99" data "Portugal Graham's Vintage Port 2007 79.99" data "Argentina Monteviejo 'Festivo' Malbec Mendoza 2009 10.99" data "Chile Tabali Pinot Noir Reserva Limari Valley 2008 11.99" data "Germany Schloss Saarstein Pinot Blanc 2008 18.99" data "Germany Mönchof Ürziger Würzgarten Riesling Kabinet 2009 17.99" data "Canada Henry of Pelham Riesling Ice Wine Niagra 2007 44.99" data "Italy Valdicava Brunello di Montalcino 2006 98.88" data "Italy Allegrini 'Palazzo della Torre' 2007 15.99" data "Italy Frescobaldi Nipozzano Chianti Rufina Reserva 2007 18.99" data "Italy Zaccagnini Montepulciano d' Abruzzo 2007 14.99" data "Spain Quinta Sardonia Ribera del Duero 2006 39.99" data "New ZealandKim Crawford Sauvignon Blanc Marlborough 2010 13.99" data "New ZealandWaipara Springs Pinot Noir Waipara 2008 15.99" data "Australia Penley Estate 'Hyland' Shiraz Coonawarra 2007 14.99" data "Greece Thimiopoulos 'Uranos' Xinomavro Naoussa 2007 29.99" data "Mexico Casa de Piedra Vino de Piedra 2005 59.99" data "" I = 0 do while I < MAX_ITEMS I = I + 1 read SHOP'ARRAY(I) if SHOP'ARRAY(I) = "" exit SHOP'ITEMS = I loop COLDEF1$ = "" ! [104] COLDEF1$ = COLDEF1$ + "1~11~Region~S<~Dspwid=5~~" ! [104] COLDEF1$ = COLDEF1$ + "12~45~Wine~SW<~Dspwid=18~~" ! [104] COLDEF1$ = COLDEF1$ + "57~4~Vintage~S|<~Dspwid=4~~" ! [104] COLDEF1$ = COLDEF1$ + "61~8~Price~#>~Mask=####.##~~" ! [104] ! tree2 coldef nearly the same, but we define a DragDropExit code ! (fired when items from tree1 are dragged over and dropped on tree2) COLDEF2$ = "" ! [104] COLDEF2$ = COLDEF2$ + "1~11~Region~S<~Dspwid=5~DragDropExit=101~~" ! [104] COLDEF2$ = COLDEF2$ + "12~45~Wine~SW<~Dspwid=18~~" ! [104] COLDEF2$ = COLDEF2$ + "57~4~Vintage~S|~Dspwid=4~~" ! [104] COLDEF2$ = COLDEF2$ + "61~8~Price~#>~Mask=####.##~~" ! [104] CART'ITEMS = 0 ! tree2 starts out empty ! Set up Tree1 XTRCTL options... SHOP'XTR.CTLNO = -1 ! 1st XTREE ctl # (auto-assign) SHOP'XTR.ITEMLINES = 2 ! (max) # lines per row to show (see XTF_VARY) SHOP'XTR.SHOWGRID = 1 ! show grid lines SHOP'XTR.GRIDSTYLE = XTRGRID_BOTH ! solid vertical & horizontal SHOP'XTR.SELECTAREA = XTRSEL_STY_ALL ! selection area is entire row SHOP'XTR.SCROLLTIPS = 1 ! show scroll tips SHOP'XTR.FLYBY = 1 ! show flyby highlighting SHOP'XTR.TRUNCATED = 1 ! show truncation indicators ! Set up Tree1 flags SHOP'XFLG.FLAGS = 0 SHOP'XFLG.FLAGS2 = 0 ! mandatory flags for this app... SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_XYXY ! alt coords (srow,scol,erow,ecol) SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_MODELESS ! Leave box on screen after exit SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_COLDFX ! [104] using COLDEF SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_MSEL ! multi-select ! Remaining SHOP'XFLG.FLAGS are optional - you can experiment with them SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_FKEY ! Allow F1-F16 SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_LEFT ! Left arrow (Exitcode -40) SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_RIGHT ! Right arrow (Exitcode -41) SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_UP ! Up arrow (Exitcode -42) SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_TAB ! TAB (Exitcode -44) SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_HOME ! Right arrow (Exitcode -45) SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_END ! Right arrow (Exitcode -46) SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_TIMOUT ! 200 sec timeout (auto ESC) SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_SORT ! Allow column sorting SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_REORD ! Allow reordering of columns SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_VARY ! Vari. ht rows (see SHOP'XTR.ITEMLINES) SHOP'XFLG.FLAGS2 = SHOP'XFLG.FLAGS2 or XTF2_DRAGDROP2 ! [104] enable inter-tree drag/drop ! Set up Tree2 (nearly same as Tree1) CART'XTR = SHOP'XTR CART'XFLG = SHOP'XFLG CART'XFLG.FLAGS = CART'XFLG.FLAGS or XTF_DEL ! [101] allow DEL in 2nd ctl also ! [102] Note use of VK_xrF### syntax below. First, the SHOP'XTR.KBDSTR ! [102] is only 10 chars long and we need a trailing null, so ! [102] don't make it any longer!! ! [102] Also, the _xrF### syntax supports right click by sending ! [102] EXITCODE = +### SHOP'XTR.KBDSTR = "VK_xrF301" ! [102] XTREE #1 is F301 (exitcode -301/+301) CART'XTR.KBDSTR = "VK_xrF302." ! [102] XTREE2 is F302 (exitcode -302/+302) ! set up tree coordinates (same size, side by side) SHOP'XSROW = 5 SHOP'XSCOL = 2 SHOP'XEROW = SHOP'XSROW + 10 SHOP'XECOL = SHOP'XSCOL + 32 CART'XSROW = SHOP'XSROW ! same starting row CART'XSCOL = SHOP'XECOL + 12 ! tree2 16 cols to right of tree1 CART'XEROW = SHOP'XEROW ! same ending row (10 high) CART'XECOL = CART'XSCOL + 32 ! different ending cols (25 wide) ? tab(-1,0);"XTRA4: Dueling XTREEs (with inter-tree transfer)" ! display labels above the two trees to identify them xcall AUI,AUI_CONTROL,CTLOP_ADD,"lblShop","Wine Selection (Shop)",MBST_ENABLE, & MBF_STATIC,NUL_CMD$,NUL_FUNC$,NUL_CSTATUS,SHOP'XSROW-2,SHOP'XSCOL,SHOP'XSROW-1,SHOP'XECOL, & NUL_FGC,NUL_BGC,FA_EXTRABOLD,180 xcall AUI,AUI_CONTROL,CTLOP_ADD,"lblCart","Your Shopping Cart",MBST_ENABLE, & MBF_STATIC,NUL_CMD$,NUL_FUNC$,NUL_CSTATUS,CART'XSROW-2,CART'XSCOL,CART'XSROW-1,CART'XECOL, & NUL_FGC,NUL_BGC,FA_EXTRABOLD,180 ![105] was lblShop (duplicate) ! Create buttons for moving items from one box to the other ! [102] Note: we use the VK_xrF### virtual key syntax to enable ! [102] exitcodes for both left and right click on the button; ! [102] for left click, we get EXITCODE -###; for right, +### xcall AUI,AUI_CONTROL,CTLOP_ADD,COPYID$,"Add to Cart >",MBST_DISABLE,MBF_BUTTON+MBF_KBD, & "VK_xrF101",NUL_FUNC$,NUL_CSTATUS,SHOP'XSROW+4,SHOP'XECOL+2,SHOP'XSROW+5,CART'XSCOL-2 ![105]COPYID$ xcall AUI,AUI_CONTROL,CTLOP_ADD,DELID$,"Remove",MBST_DISABLE,MBF_BUTTON+MBF_KBD, & "VK_xrF102",NUL_FUNC$,NUL_CSTATUS,SHOP'XSROW+7,SHOP'XECOL+2,SHOP'XSROW+8,CART'XSCOL-2 ![105]DELID$ ! Create a group of buttons to provide some interest plus alternate ! methods of selecting either control or exiting. (The buttons ! for the 2 controls send the same code as clicking on the control) ! groupbox (GRPID) ![105] xcall AUI,AUI_CONTROL,CTLOP_ADD,GRPID,"Superfluous Buttons",MBST_ENABLE, & ! MBF_BUTTON+MBF_GROUPBOX+MBF_LFJUST+MBF_ALTPOS, & ! "","",STATUS,SHOP'XEROW+4,SHOP'XECOL-15,SHOP'XEROW+7,CART'XSCOL+15 xcall AUI,AUI_CONTROL,CTLOP_ADD,GRPID$,"Superfluous Buttons",MBST_ENABLE, & MBF_BUTTON+MBF_GROUPBOX+MBF_LFJUST+MBF_ALTPOS, & NUL_CMD$,NUL_FUNC$,NUL_CSTATUS,SHOP'XEROW+4,SHOP'XECOL-15,SHOP'XEROW+7,CART'XSCOL+15 ! [105] ! 3 buttons within groupbox ! "shop" button xcall AUI,AUI_CONTROL,CTLOP_ADD,"btnShop","Shop",MBST_ENABLE, & MBF_BUTTON+MBF_KBD+MBF_ALTPOS, & "VK_xF201",NUL_FUNC$,NUL_CSTATUS,2,5,3,13,NUL_FGC,NUL_BGC, & NUL_FONTATTR,NUL_FONTSCALE,NUL_FONTFACE$, & "Activate (put focus on) 'shop' control",GRPID$ ! [105] GRPID$ [106] ! "exit" button xcall AUI,AUI_CONTROL,CTLOP_ADD,"btnExit","Exit",MBST_ENABLE, & MBF_BUTTON+MBF_KBD+MBF_ALTPOS, & "VK_ESC",NUL_FUNC$,NUL_CSTATUS,2,18,3,26,NUL_FGC,NUL_BGC, & NUL_FONTATTR,NUL_FONTSCALE,NUL_FONTFACE$, & "Exit program",GRPID$ ! [105] GRPID$ [106] ! "cart" button xcall AUI,AUI_CONTROL,CTLOP_ADD,"btnCart","Cart",MBST_ENABLE, & MBF_BUTTON+MBF_KBD+MBF_ALTPOS, & "VK_xF202",NUL_FUNC$,NUL_CSTATUS,2,31,3,39,NUL_FGC,NUL_BGC, & NUL_FONTATTR,NUL_FONTSCALE,NUL_FONTFACE$, & "Activate (put focus on) 'cart' control",GRPID$ ! [105] GRPID$ [106] ! display the 2 controls... SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS or XTF_NOSEL ! display only, no selection SHOP'XTR.OPCODE = XTROP_CREATE SHOP'ANSWER$ = FILL$("0",MAX_ITEMS) ! init answer array to all unselected call XTREE1 SHOP'XFLG.FLAGS = SHOP'XFLG.FLAGS and not XTF_NOSEL ! remove NOSEL flag after initial display CART'XTR.OPCODE = XTROP_CREATE ! (same sequence for 2nd tree) CART'XFLG.FLAGS = CART'XFLG.FLAGS or XTF_NOSEL CART'ANSWER$ = FILL$("0",MAX_ITEMS) ! init answer array to all unselected call XTREE2 CART'XFLG.FLAGS = CART'XFLG.FLAGS and not XTF_NOSEL EXITCODE = 0 do ! [102] Skip the eventwait if we already have an exitcode (this ! [102] would happen, for example, if we had clicked on a button ! [102] to exit from a previous XTREE operation) if EXITCODE = 0 then ! [104] disable "Cart" button if cart empty if CART'ITEMS = 0 then xcall AUI,AUI_CONTROL,CTLOP_CHG,"btnCart","",MBST_DISABLE else xcall AUI,AUI_CONTROL,CTLOP_CHG,"btnCart","",MBST_ENABLE endif ! shop button always enabled except when in shop xtree xcall AUI,AUI_CONTROL,CTLOP_CHG,"btnShop","",MBST_ENABLE ! [101] put focus on button group, wait for something to happen ! [101] (only choices are moving the focus, or clicking on one ! [101] of the xtrees) ![105] EVW'GRPID = GRPID ! ID of button group EVW'GRPID$ = GRPID$ ! [105] (alphanumeric) ID of button group EVW'CTLID = 0 ! put focus on first button in group EVW'FLAGS = EVW_NEXT+EVW_DESCEND ! descend into group, pick next avail TRACE.PRINT "Button group eventwait grpid="+EVW'GRPID$+", ctlid="+EVW'CTLID+", exitcode="+EXITCODE+"..." ![105] xcall AUI,AUI_EVENTWAIT,EVW'GRPID$,EVW'CTLID,EXITCODE,EVW'FLAGS ! [105] EVW'GRPID$ TRACE.PRINT " Eventwait exitcode = "+EXITCODE ! [104] endif ! [102] EXITCODE Notes: ! -101/+101 = "Copy >" button (left click/right click) ! -201 = "XTREE#1" button; ! -202 = "XTREE#2" button; ! -301/+301 = click on XTREE 1 ctl while inactive (left/right) ! -302/+302 = click on XTREE 2 ctl while inactive (left/right) ! 3 = they arrowed out of group (up or to left) ! 5 = they arrowed out of group (down or right) ! (To get EXITCODEs 3 and 5, we need to have the EVW_NOWRAP option ! set in the EVW'FLAGS; the logic below treats these actions, if ! the occur, as being the same as clicking on the first or last btn) switch EXITCODE case 1 ! EXIT button (ESC) ! [105] (move this below loop) exit case 3 EXITCODE = -201 ! see above notes CNO = -EXITCODE - 200 exit case 5 EXITCODE = -202 ! see above notes CNO = -EXITCODE - 200 exit case -201 ! click on "shop" button case -202 ! click on "cart" button CNO = -EXITCODE - 200 exit case -301 ! click on inactive tree 1 case -302 ! click on inactive tree 2 CNO = -EXITCODE - 300 exit case 101 ! right click on "Add to Cart >" button xcall MSGBOX, & "Clicking on this button causes the selected items in " & + "in the left list to be copied to the right list. You " & + "could also accomplish the same thing when the left " & + "list has the focus, by double-clicking or hitting ENTER " & + "on the item you want to copy.", "XTR4 Help Message", & MBTN_OK,MBICON_ICON,MBMISC_TASKMODAL EXITCODE = 0 exit case 201 ! right click on "Delete" button xcall MSGBOX, & "Clicking on this button causes the selected items in " & + "in the right list to be deleted. (This uses SHOP'XTR.OPCODE " & + "XTR_DELSEL, i.e. 5, to delete just selected items)", "XTR4 Help Message", & MBTN_OK,MBICON_ICON,MBMISC_TASKMODAL EXITCODE = 0 exit case 301 ! right click left tree xcall MSGBOX, & "Not knowing why you right-clicked on the left tree, " & + "we just display this message.", "XTR4 Help Message", & MBTN_OK,MBICON_ICON,MBMISC_TASKMODAL EXITCODE = 0 exit case 302 ! right click on right xtree xcall MSGBOX, & "Not knowing why you right-clicked on the right tree, " & + "we just display this message.", "XTR4 Help Message", & MBTN_OK,MBICON_ICON,MBMISC_TASKMODAL EXITCODE = 0 exit default ! Let other exitcodes just fall thru to button eventwait ! (These would include all the navigational exitcodes for getting ! out of the XTREE) EXITCODE = 0 exit endswitch if EXITCODE # 1 then EXITCODE = 0 if CNO = 1 then SHOP'XTR.OPCODE = XTROP_RESELECT call XTREE1 elseif CNO = 2 then CART'XTR.OPCODE = XTROP_RESELECT call XTREE2 else ? chr(7) endif endif loop until EXITCODE = 1 ! [105] Delete everything upon ESC (EXITCODE 1) ! (Of course we could just do a tab(-1,0) but this is better exercise) if SHOP'XTR.CTLID then ! delete first control SHOP'XTR.OPCODE = XTROP_DELETE call XTREE1 SHOP'XTR.CTLID = 0 endif if CART'XTR.CTLID then ! delete second control CART'XTR.OPCODE = XTROP_DELETE call XTREE2 CART'XTR.CTLID = 0 endif ! [101] delete the buttons too xcall AUI,AUI_CONTROL,CTLOP_DEL,COPYID$ ! [105] COPYID$ xcall AUI,AUI_CONTROL,CTLOP_DEL,DELID$ ! [105] DELID$ xcall AUI,AUI_CONTROL,CTLOP_DEL,GRPID$ ! [105] GRPID$ ! [105] and the bold labels xcall AUI,AUI_CONTROL,CTLOP_DEL,"lblShop" ! [105] Wine Selection xcall AUI,AUI_CONTROL,CTLOP_DEL,"lblCart" ! [105] Your Shopping Cart xcall AUI,AUI_CONTROL,CTLOP_DEL,"lblTotal" ! [105] Cart Total ? tab(22,1);"End" END !----------------------------------------------------------------------- ! Operations on 1ST XTREE ! Inputs: ! SHOP'XTR, SHOP'XFLG ! Notes: ! We XCALL XTREE for the 1st tree, and wait for an exitcode. ! For requests to copy items to 2nd tree, perform the operation and ! return to waiting in the first tree. For any other exitcodes, just ! return to the caller. ! - !----------------------------------------------------------------------- XTREE1: ! [101] enable Add to Cart button, disable DEL button xcall AUI,AUI_CONTROL,CTLOP_CHG,COPYID$,"",MBST_ENABLE ![105] COPYID$ xcall AUI,AUI_CONTROL,CTLOP_CHG,DELID$,"",MBST_DISABLE ![105] DELID$ ! [104] enable "Cart" button, disable "Shop" button xcall AUI,AUI_CONTROL,CTLOP_CHG,"btnCart","",MBST_ENABLE xcall AUI,AUI_CONTROL,CTLOP_CHG,"btnShop","",MBST_DISABLE do ! keep calling TREE1 until some reason not to... TRACE.PRINT "Calling XTREE1; op="+SHOP'XTR.OPCODE+", SHOP'ANSARY="+SHOP'ANSWER$[1,15]+"..." xcall XTREE,SHOP'XSROW,SHOP'XSCOL,SHOP'ANSARY(1),SHOP'ARRAY(1),SHOP'ITEMS,COLDEF1$,EXITCODE, & SHOP'XEROW,SHOP'XECOL,SHOP'XFLG,"",0,SHOP'XTR TRACE.PRINT " exitcode="+EXITCODE+" SHOP'ANSARY="+SHOP'ANSWER$[1,15]+"..." ! Select (or dragdrop, or "Add to Cart>") sends a copy of selected item(s) to 2nd tree if (EXITCODE=0 or EXITCODE=-101) and instr(1,SHOP'ANSWER$,"1") > 0 then ! (at least 1 selected item) ! Note: CART'ARRAY() contains all the items ever added to the 2nd tree. If they were ! added and then removed, the array entry is just empty (but still occupying a space). ! This is how XTROP_DELSEL works (it doesn't really "delete" the items but makes them ! invisible). That may not be the best method for such a simple situation (i.e. just ! replacing the entire control contents with the non-deleted items might be better), ! but it does test/illustrate the XTROP_DELSEL operation. (One downside of this scheme ! is that we don't reuse the deleted slots, so we may run out of space after several ! adds/deletes, even though the tree looks empty.) ADDCOUNT = 0 for I = 1 to SHOP'ITEMS if (SHOP'ANSARY(I) = "1") then ! for each selected item in tree1 CART'ITEMS = CART'ITEMS + 1 if CART'ITEMS <= MAX_ITEMS then CART'ARRAY(CART'ITEMS)=SHOP'ARRAY(I) ! transfer it to tree 2 ADDCOUNT = ADDCOUNT + 1 TRACE.PRINT " Adding CART'ARRAY("+CART'ITEMS+") "+CART'ARRAY(CART'ITEMS) else TRACE.PRINT " Cannot add item "+I+": CART'ARRAY() is full (even if it looks empty)" endif endif next I SHOP'ANSWER$ = "" ! clear selections from tree 1 now if ADDCOUNT > 0 then CART'XFLG.FLAGS = CART'XFLG.FLAGS or XTF_NOSEL ! display only TRACE.PRINT "Calling XTREE2 to append "+ADDCOUNT+" items..." CART'XTR.OPCODE = XTROP_APPEND ! note: instead of specifying the entire data array, we specify the starting element we want to add xcall XTREE,CART'XSROW,CART'XSCOL,CART'ANSARY(1),CART'ARRAY(CART'ITEMS-ADDCOUNT+1),ADDCOUNT, & COLDEF2$,EXITCODE,CART'XSROW,CART'XSCOL,CART'XFLG,"",0,CART'XTR TRACE.PRINT " exitcode = "+EXITCODE+" CART'ANSARY="+CART'ANSWER$[1,15]+"..." call DISPLAY'CART'TOTAL CART'XFLG.FLAGS = CART'XFLG.FLAGS and not XTF_NOSEL ! remove display-only flag endif ! as a convenience, if only 1 item selected, move selection down 1 so ! user can just hit ENTER repeatedly to transfer items... ++ifdef NEVER ! (this code isn't working right) if (ADDCOUNT = 1) then J = instr(1,SHOP'ANSWER$,"1") + 1 ! position of first selected item SHOP'ANSWER$ = FILL$("0",SHOP'ITEMS) if (J <= SHOP'ITEMS) then TRACE.PRINT "Auto-selecting item #"+J SHOP'ANSARY(J) = "1" endif SHOP'XTR.TARGETROW = 0 endif ++endif else exit ! exit from loop endif loop return !----------------------------------------------------------------------- ! Operations on 2nd XTREE ! Inputs: ! CART'XTR, CART'XFLG, !----------------------------------------------------------------------- XTREE2: ! [101] enable DEL button, disable COPY> button xcall AUI,AUI_CONTROL,CTLOP_CHG,COPYID$,"",MBST_DISABLE ![105] COPYID$ xcall AUI,AUI_CONTROL,CTLOP_CHG,DELID$,"",MBST_ENABLE ![105] DELID$ ! [104] disable "Cart" button, enable "Shop" button xcall AUI,AUI_CONTROL,CTLOP_CHG,"btnCart","",MBST_DISABLE xcall AUI,AUI_CONTROL,CTLOP_CHG,"btnShop","",MBST_ENABLE do TRACE.PRINT "Calling XTREE2; op="+CART'XTR.OPCODE+", CART'ANSARY="+CART'ANSWER$[1,15]+"..." CART'XTR.NFSELSTYLE = XTNFS_NONE ! don't show any inactive tree2 selections xcall XTREE,CART'XSROW,CART'XSCOL,CART'ANSARY(1),CART'ARRAY(1),CART'ITEMS,COLDEF2$,EXITCODE, & CART'XEROW,CART'XECOL,CART'XFLG,"",0,CART'XTR TRACE.PRINT " exitcode = "+EXITCODE+", CART'ANSARY="+CART'ANSWER$[1,15]+"..." call DISPLAY'CART'TOTAL if (EXITCODE=-47 or EXITCODE=-102) then ! DEL key or REMOVE button ![106] Change deletion logic to just replace the entire cart with a new ![106] array, eliminating the deleted items. (This is more appropriate ![106] for the situation.) ![106] ! Tell xtree to remove them from the tree display... ![106] CART'XTR.OPCODE = XTROP_DELSEL ! delete selected item(s) ![106] CART'XFLG.FLAGS = CART'XFLG.FLAGS or XTF_NOSEL ! just delete and exit ![106] TRACE.PRINT "Calling XTREE2 to delete selected item(s), CART'ANSARY="+CART'ANSWER$[1,15]+"..." ![106] ! note: if passing an element specification for the answer param (as we are here) ![106] ! we must set the ITEMCOUNT to the number of items in the tree! ![106] xcall XTREE,CART'XSROW,CART'XSCOL,CART'ANSARY(1),CART'ARRAY(1),CART'ITEMS,COLDEF2$,EXITCODE, & ![106] CART'XEROW,CART'XECOL,CART'XFLG,"",0,CART'XTR ! [104] was PROMPT,XTRCTL2 ![106] CART'XFLG.FLAGS = CART'XFLG.FLAGS and not XTF_NOSEL ![106] TRACE.PRINT " exitcode = "+EXITCODE+", CART'ANSARY="+CART'ANSWER$[1,15]+"..." ![106] Remove deleted items from out cart array (copy undeleted items to TEMP array, ! ![106] then copy back to CART array) DELCNT = 0 J = 0 for I = 1 to CART'ITEMS if CART'ANSARY(I) = "0" then ! item remains in cart J = J + 1 TEMP'ARRAY(I-DELCNT) = CART'ARRAY(I) else DELCNT = DELCNT + 1 TRACE.PRINT " Deleting item #"+I endif next I CART'ITEMS = CART'ITEMS - DELCNT if CART'ITEMS = 0 then ! everything deleted, just clear cart array CART'ARRAYX = FILL$(chr(0),sizeof(CART'ARRAYX)) ! start with clear array elseif DELCNT > 0 then ! some (not all) deleted (copy temp array back) for I = 1 to CART'ITEMS CART'ARRAY(I) = TEMP'ARRAY(I) next I endif CART'ANSWER$ = FILL$("0",CART'ITEMS) ! there are no selected items in cart after delete TRACE.PRINT " cart now contains "+CART'ITEMS+" items " ![106] call DISPLAY'CART'TOTAL CART'XTR.OPCODE = XTROP_REPLACE ! [106] replace and reselect else exit endif loop return DISPLAY'CART'TOTAL: ! [104] display the total value of the cart TOTAL = 0 for I = 1 to CART'ITEMS ITEMREC = CART'ARRAY(I) TOTAL = TOTAL + val(ITEMREC.PRICE) next I xcall AUI,AUI_CONTROL,CTLOP_ADD,"lblTotal","Cart Total: "+(TOTAL using "##,###.##"),MBST_ENABLE, & MBF_STATIC+MBF_RTJUST,NUL_CMD$,NUL_FUNC$,NUL_CSTATUS,CART'XEROW+2,CART'XSCOL,CART'XEROW+2,CART'XECOL, & NUL_FGC,NUL_BGC,FA_EXTRABOLD,120,NUL_FONTFACE$ return