Author Topic: Mighty Menu?  (Read 2987 times)

0 Members and 1 Guest are viewing this topic.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Mighty Menu?
« on: October 06, 2021, 06:22:00 pm »
I bet Steve is getting mighty tired of these menu titles, but since we are on the subject of menus...

Code: QB64: [Select]
  1. REM mydemo% = -1
  2. DIM UI AS UserInput
  3. REDIM Menu$(100)
  4.  
  5. TYPE UserInput
  6.     KeyPress AS STRING
  7.     KeyCombos AS INTEGER
  8.     MbStatus AS INTEGER
  9.     MbEnvoked AS INTEGER
  10.     drag AS INTEGER
  11.     DoubleClick AS INTEGER
  12.     MbLeftx AS INTEGER
  13.     MbLefty AS INTEGER
  14.     mx AS INTEGER
  15.     oldmx AS INTEGER
  16.     my AS INTEGER
  17.     oldmy AS INTEGER
  18.  
  19. IF demo% THEN PRINT "Press keys or use mouse for demo.";
  20.     MenuSetup = MenuSetup + 1: GOSUB MenuSetup
  21.     DO
  22.         CALL keyboard_mouse(UI, mydemo%)
  23.         IF UI.MbStatus < 0 AND UI.MbEnvoked = 0 THEN
  24.             SOUND 1000, .1
  25.             UI.MbEnvoked = -1
  26.         END IF
  27.  
  28.         SELECT CASE UI.MbStatus
  29.             CASE -1
  30.                 GOSUB FindMenu
  31.  
  32.                 SELECT CASE x$
  33.                     CASE Menu$(1)
  34.                         LOCATE 1, 1: PRINT Menu$(1); "                  ";
  35.                         _DELAY 2
  36.                         EXIT DO
  37.                     CASE Menu$(2)
  38.                         LOCATE 1, 1: PRINT Menu$(2); "                  ";
  39.                     CASE Menu$(3)
  40.                         LOCATE 1, 1: PRINT Menu$(3); "                  ";
  41.                     CASE Menu$(4)
  42.                         LOCATE 1, 1: PRINT Menu$(4); "                  ";
  43.                     CASE Menu$(5)
  44.                         END
  45.                 END SELECT
  46.  
  47.         END SELECT
  48.     LOOP
  49. LOOP UNTIL MenuSetup = 2
  50.  
  51. MenuSetup:
  52. SELECT CASE MenuSetup
  53.     CASE 1
  54.         MenuType% = 1
  55.         DrawBox% = -1
  56.         MenuX = 0 ' Auto-Center
  57.         MenuY = 0 ' Auto-Center
  58.         Menu$(1) = "[Enter] Next Menu"
  59.         Menu$(2) = "[F1] Help"
  60.         Menu$(3) = "[F5] Save"
  61.         Menu$(4) = "[F12] Run Demo"
  62.         Menu$(5) = "[Esc] End"
  63.         Menu$(6) = ""
  64.         Menu$(7) = ""
  65.         Menu$(8) = ""
  66.         Menu$(9) = ""
  67.         Menu$(10) = ""
  68.     CASE 2
  69.         MenuType% = 2
  70.         DrawBox% = 0
  71.         MenuX = 0 ' Auto-Center
  72.         MenuY = 0 ' Auto-Center
  73.         Menu$(1) = "[Enter] Next Menu"
  74.         Menu$(2) = "[F1] Help"
  75.         Menu$(3) = "[F5] Save"
  76.         Menu$(4) = "[F12] Run Demo"
  77.         Menu$(5) = "[Esc] End"
  78.         Menu$(6) = ""
  79.         Menu$(7) = ""
  80.         Menu$(8) = ""
  81.         Menu$(9) = ""
  82.         Menu$(10) = ""
  83.  
  84. FOR noe = UBOUND(Menu$) TO 1 STEP -1
  85.     IF LEN(Menu$(noe)) THEN EXIT FOR
  86.  
  87. SELECT CASE MenuType%
  88.     CASE 1
  89.         x = 0
  90.         FOR i = 1 TO noe
  91.             IF LEN(Menu$(i)) > x THEN x = LEN(Menu$(i))
  92.         NEXT
  93.  
  94.         IF MenuX = 0 THEN MenuX = INT(_WIDTH / 2 + 1 - (x / 2))
  95.         IF MenuY = 0 THEN MenuY = INT(_HEIGHT / 2 - (noe / 2) - 1)
  96.  
  97.         IF DrawBox% THEN GOSUB DrawBox
  98.  
  99.         FOR i = 1 TO noe
  100.             LOCATE MenuY + i - 1, MenuX
  101.             PRINT Menu$(i);
  102.         NEXT
  103.     CASE 2
  104.         Menu$ = "": x$ = "": k = 0
  105.         FOR i = 1 TO noe
  106.             IF LEN(Menu$(i)) THEN
  107.                 k = k + 1: Menu$ = Menu$ + CHR$(255) + Menu$(i)
  108.             END IF
  109.         NEXT
  110.         j = (_WIDTH - LEN(Menu$)) \ k
  111.         IF j > 5 THEN j = 5
  112.         Menu$ = MID$(Menu$, 2) + CHR$(255)
  113.         DO UNTIL INSTR(Menu$, CHR$(255)) = 0
  114.             a$ = CHR$(255) + MID$(Menu$, 1, INSTR(Menu$, CHR$(255)) - 1) 'SPACE$(j)
  115.             Menu$ = MID$(Menu$, INSTR(Menu$, CHR$(255)) + 1)
  116.             x$ = x$ + a$ + SPACE$(j)
  117.         LOOP
  118.         Menu$ = _TRIM$(x$)
  119.         CLS
  120.         LOCATE _HEIGHT, _WIDTH \ 2 - LEN(Menu$) \ 2
  121.         PRINT Menu$;
  122.  
  123. DrawBox:
  124. LOCATE MenuY - 1, MenuX - 2
  125. PRINT CHR$(218) + STRING$(x + 2, 196) + CHR$(191)
  126. FOR i = 1 TO noe
  127.     LOCATE , MenuX - 2
  128.     PRINT CHR$(179);: LOCATE , POS(0) + x + 2: PRINT CHR$(179)
  129. LOCATE , MenuX - 2
  130. PRINT CHR$(192) + STRING$(x + 2, 196) + CHR$(217);
  131.  
  132. FindMenu:
  133. SELECT CASE MenuType%
  134.     CASE 0
  135.         CLS: PRINT "You did not assign a value to the variable: MenuType": END '''
  136.     CASE 1 ' Vertical
  137.         IF UI.my >= MenuY AND UI.my <= MenuY + noe - 1 THEN
  138.             x$ = ""
  139.             FOR i = MenuX TO MenuX + x
  140.                 a$ = CHR$(SCREEN(UI.my, i))
  141.                 x$ = x$ + a$
  142.                 IF flag = 0 THEN IF a$ <> " " THEN flag = i
  143.             NEXT
  144.             x$ = _TRIM$(x$)
  145.             IF UI.mx >= flag AND UI.mx <= flag + LEN(x$) THEN
  146.                 IF VAL(x$) THEN x$ = LTRIM$(STR$(VAL(x$)))
  147.             END IF
  148.             flag = 0
  149.         END IF
  150.     CASE 2 ' Horizontal
  151.         x$ = ""
  152.         FOR i = 1 TO _WIDTH
  153.             a$ = CHR$(SCREEN(UI.my, i))
  154.             x$ = x$ + a$
  155.         NEXT
  156.         x$ = CHR$(255) + x$ + CHR$(255)
  157.         x$ = _TRIM$(MID$(x$, 1, INSTR(UI.mx + 1, x$, CHR$(255)) - 1))
  158.         IF LEN(x$) <= UI.mx THEN
  159.             x$ = "" ' Mouse is not on a menu item.
  160.         ELSE
  161.             x$ = _TRIM$(MID$(x$, _INSTRREV(x$, CHR$(255)) + 1))
  162.         END IF
  163.     CASE ELSE
  164.         CLS: PRINT "You assigned a value to MenuType that was out-of-range.": END '''
  165.  
  166. SUB keyboard_mouse (UI AS UserInput, mydemo%)
  167.     STATIC z1, lclick
  168.  
  169.     _LIMIT 30
  170.  
  171.     DEF SEG = 0
  172.     IF PEEK(1047) MOD 16 = 1 OR PEEK(1047) MOD 16 = 2 THEN
  173.         UI.KeyCombos = 1 ' Shift  % = -1 ELSE shift% = 0
  174.     ELSEIF PEEK(1047) MOD 16 = 3 OR PEEK(1047) MOD 16 = 4 THEN
  175.         UI.KeyCombos = 2 ' Ctrl  % = -1 ELSE ctrl% = 0
  176.     ELSEIF PEEK(1047) MOD 16 = 7 OR PEEK(1047) MOD 16 = 8 THEN
  177.         UI.KeyCombos = 3 ' Alt  % = -1
  178.     ELSEIF PEEK(1047) MOD 16 = 5 OR PEEK(1047) MOD 16 = 6 THEN
  179.         UI.KeyCombos = 4 ' Ctrl+Shift  % = -1 ELSE ctrlshift% = 0
  180.     ELSE
  181.         UI.KeyCombos = 0
  182.     END IF
  183.     DEF SEG
  184.  
  185.     IF mydemo% THEN GOSUB check_UI.KeyCombos
  186.  
  187.     UI.KeyPress = INKEY$
  188.     IF LEN(UI.KeyPress) THEN ' A key was pressed.
  189.         UI.MbEnvoked = 0: UI.MbLeftx = 0
  190.         SELECT CASE LEN(UI.KeyPress)
  191.             CASE 1 ' 1-byte key A-Z, etc.
  192.                 IF mydemo% THEN mydemo% = 1: GOSUB mydemo
  193.                 SELECT CASE UI.KeyPress
  194.                     ' Place key selection routine here...
  195.                     CASE CHR$(27): SYSTEM
  196.                 END SELECT
  197.             CASE 2 '2-byte key F1-F12, etc.
  198.                 IF mydemo% THEN mydemo% = 2: GOSUB mydemo
  199.                 SELECT CASE RIGHT$(UI.KeyPress, 1)
  200.                     ' Place key selection routine here...
  201.                 END SELECT
  202.         END SELECT
  203.     ELSE ' Check for mouse input since no keyboard input was detected.
  204.  
  205.         IF lclick THEN ' Check timer for double-clicks.
  206.             IF TIMER < z1 THEN z1 = z1 - 86400 ' Midnight adjustment.
  207.             IF TIMER - z1 > .33 THEN lclick = 0 ' Too much time ellapsed for a double click.
  208.         END IF
  209.  
  210.         WHILE _MOUSEINPUT
  211.             mw = mw + _MOUSEWHEEL ' Check for mouse wheel use.
  212.         WEND
  213.  
  214.         ' Get mouse status.
  215.         UI.mx = _MOUSEX
  216.         UI.my = _MOUSEY
  217.         lb = _MOUSEBUTTON(1)
  218.         rb = _MOUSEBUTTON(2)
  219.         mb = _MOUSEBUTTON(3)
  220.  
  221.         SELECT CASE UI.MbEnvoked
  222.             CASE 0
  223.                 IF lb OR rb OR mb THEN
  224.  
  225.                 END IF
  226.             CASE 1
  227.                 IF lb OR rb OR mb THEN UI.MbEnvoked = 0
  228.             CASE -1
  229.                 IF lb = 0 AND rb = 0 AND mb = 0 THEN UI.MbEnvoked = 0
  230.         END SELECT
  231.  
  232.         IF UI.MbStatus < 0 THEN ' Mouse button pressed. UI.MbStatus identity is by number. -1=left, -2=right, -3=middle.
  233.             SELECT CASE UI.MbStatus
  234.                 CASE -1 ' Left button was pressed.
  235.                     IF lb = 0 THEN ' Left button released.
  236.                         SELECT CASE lclick ' Single or double click analysis.
  237.                             CASE 0
  238.                                 IF mydemo% THEN mydemo% = 3: GOSUB mydemo
  239.                                 lclick = lclick + 1
  240.                             CASE ELSE ' Double click. Completed upon 2nd left button release.
  241.                                 IF mydemo% THEN mydemo% = 11: GOSUB mydemo
  242.                                 UI.DoubleClick = -1
  243.                                 lclick = 0
  244.                         END SELECT
  245.                         UI.MbStatus = 1
  246.  
  247.                         IF UI.MbLeftx THEN
  248.                             IF UI.mx <> UI.MbLeftx OR UI.my <> UI.MbLefty THEN UI.MbStatus = 0: lclick = 0
  249.                             UI.MbLeftx = 0: UI.MbLefty = 0
  250.                         END IF
  251.  
  252.                         IF UI.drag THEN UI.drag = 0
  253.                     ELSE ' Left button is being held down. Check for UI.drag.
  254.                         IF UI.mx <> UI.oldmx OR UI.my <> UI.oldmy THEN ' Mouse cursor has moved. UI.drag.
  255.                             IF mydemo% THEN mydemo% = 12: GOSUB mydemo
  256.                             UI.drag = -1
  257.                         END IF
  258.                     END IF
  259.                 CASE -2 ' Right button was pressed.
  260.                     IF rb = 0 THEN ' Right button was relased.
  261.                         IF mydemo% THEN mydemo% = 4: GOSUB mydemo
  262.                         UI.MbStatus = 2
  263.                     END IF
  264.                 CASE -3 ' Middle button was pressed
  265.                     IF mb = 0 THEN ' Middle button was released.
  266.                         IF mydemo% THEN mydemo% = 5: GOSUB mydemo
  267.                         UI.MbStatus = 3
  268.                     END IF
  269.             END SELECT
  270.         ELSE
  271.             IF lb THEN ' Left button just pressed.
  272.                 IF mydemo% THEN mydemo% = 6: GOSUB mydemo
  273.                 UI.MbStatus = -1
  274.                 IF UI.MbLeftx = 0 THEN UI.MbLeftx = UI.mx: UI.MbLefty = UI.my
  275.                 z1 = TIMER
  276.             ELSEIF rb THEN ' Right button just pressed.
  277.                 IF mydemo% THEN mydemo% = 7: GOSUB mydemo
  278.                 IF UI.MbLeftx = 0 THEN UI.MbLeftx = UI.mx: UI.MbLefty = UI.my
  279.                 UI.MbStatus = -2
  280.             ELSEIF mb THEN ' Middle button just pressed.
  281.                 IF mydemo% THEN mydemo% = 8: GOSUB mydemo
  282.                 IF UI.MbLeftx = 0 THEN UI.MbLeftx = UI.mx: UI.MbLefty = UI.my
  283.                 UI.MbStatus = -3
  284.             ELSEIF mw THEN ' Mouse wheel just moved.
  285.                 SELECT CASE mw
  286.                     CASE IS > 0 ' Scroll down.
  287.                         IF mydemo% THEN mydemo% = 9: GOSUB mydemo
  288.                     CASE IS < 0 ' Scroll up.
  289.                         IF mydemo% THEN mydemo% = 10: GOSUB mydemo
  290.                 END SELECT
  291.             END IF
  292.         END IF
  293.  
  294.         UI.oldmx = UI.mx: UI.oldmy = UI.my: mw = 0 ' Mouse position past and present.
  295.     END IF
  296.     EXIT SUB
  297.  
  298.     mydemo:
  299.     LOCATE 1, 1: PRINT "Last User Status:                                    ";
  300.     LOCATE , 19
  301.     SELECT CASE mydemo%
  302.         CASE 1
  303.             PRINT "1-byte Key = "; UI.KeyPress
  304.         CASE 2
  305.             PRINT "2-byte Key = "; UI.KeyPress
  306.         CASE 3
  307.             PRINT "Left button released."
  308.         CASE 4
  309.             PRINT "Right button released."
  310.         CASE 5
  311.             PRINT "Middle button released."
  312.         CASE 6
  313.             PRINT "Left button down."
  314.         CASE 7
  315.             PRINT "Right button down."
  316.         CASE 8
  317.             PRINT "Middle button down."
  318.         CASE 9
  319.             PRINT "Wheel scroll down."
  320.         CASE 10
  321.             PRINT "Wheel scroll up."
  322.         CASE 11
  323.             PRINT "Left button double click."
  324.         CASE 12
  325.             PRINT "Drag..."
  326.     END SELECT
  327.     mydemo% = -1
  328.     RETURN
  329.  
  330.     check_UI.KeyCombos:
  331.     IF UI.KeyCombos THEN
  332.         LOCATE 1, 50
  333.         SELECT CASE UI.KeyCombos
  334.             CASE 1
  335.                 PRINT "Shift key down.        ";
  336.             CASE 2
  337.                 PRINT "Ctrl key down.         ";
  338.             CASE 3
  339.                 PRINT "Alt key down.          ";
  340.             CASE 4
  341.                 PRINT "Ctrl + Shift key down. ";
  342.         END SELECT
  343.     ELSE
  344.         LOCATE 1, 50: PRINT SPACE$(29);
  345.     END IF
  346.     RETURN

So in time, I will reinvent one of my many wheels again, and much like the mouse routine, that this routine uses, I will have a universal menu routine. The next stage is to put the horizontal menu in. Ah, did I mention how much I love that edit post feature restored? I think I did.

So if this goes well, all that would be needed is for the user to decide on a couple of options, like the box around the vertical menu, and then just fill in as many of the menu$() arrays. Skip every-other one to space the entries. Of course, it will get more complicated. Scrolling menu for more than the height of the program window will allow, etc.

Anyway, I'd just thought I'd post what I have so far. I wish I was more comfortable with _PRINTSTRING. It would be fun to be working on a graphics clone.
 
Pete

EDIT: Added the horizontal menu option.
« Last Edit: October 06, 2021, 11:18:47 pm by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/