Ooops
October 28, 2021, 12:07:43

Author Topic: [bb] Popup menu by Nebula [ 1+ years ago ]  (Read 807 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] Popup menu by Nebula [ 1+ years ago ]
« on: June 29, 2017, 00:28:40 »
Title : Popup menu
Author : Nebula
Posted : 1+ years ago

Description : Right mouse to activate pop up menu.

Code :
Code: BlitzBasic
  1. ;
  2. ; Blitz + Native Popup menu, No dll or userlib required
  3. ;
  4. ; (c) R.v.Etten / Nebula in 2004
  5.  
  6. ;
  7. ; Currently minor visuals are added and the submenus only go one level deep. The menu's might also sometimes be slightly
  8. ; jitterisch.
  9. ;
  10. ; Functions Draw... can be adjusted to modify the visual apearance of the popup menu
  11.  
  12. ;Todo :
  13. ;
  14. ; Display key Shotcuts
  15. ; Modularize popup control structure
  16. ; Put popup collision in timer
  17. ; Large menu scrolling (scrollbar?)
  18. ; Auto adjust popup layout to size (screen)
  19. ; Blanked out text (inactive / disable / enable)
  20. ; More user level control function
  21. ; More sub menu levels
  22. ; Update popup output handling to contents
  23. ; Better interactive control
  24. ; Inline images and user controls
  25. ; Easy user level color control
  26. ;
  27. ;Todo maybe :
  28. ;
  29. ; Menu resizing animation
  30. ; Skins and oval/round popup menus
  31. ; Sound effects
  32. ; Fullscreen version
  33. ; Menu mode
  34. ; Inline animations
  35. ; Load data from Ini file
  36.  
  37. Global winwidth = 640
  38. Global winheight = 480
  39.  
  40. Global win = CreateWindow("Window",ClientWidth(Desktop())/2-winwidth/2,ClientHeight(Desktop())/2-winheight/2,winwidth,winheight,Desktop(),1+8)
  41.  
  42. Global popupfontwidth = 8
  43. Global popupfontheight = 13
  44. Global popupclose
  45. Const numpopupmenus = 4
  46. Const numpopupitems = 99
  47. Dim popupdata$(numpopupmenus,numpopupitems,22)
  48. Dim popuppoint(1) ; win,canvas switch
  49. Const popupactive = 0
  50. Const popuptext = 1
  51. Const popupwidth = 2
  52. Const popupheight = 3
  53. Const popupx = 4
  54. Const popupy = 5
  55. Const popupnumitems = 6
  56. Const popuppointer = 7 ; point to another popup menu
  57. Const popupenabled = 8
  58. Const popupline = 9
  59. Const popupmouseontop = 10
  60. Const popupoutdata = 11
  61. Const popupisinitiated = 12 ; goes in x,0,><
  62. Const popupmenuwidth = 13 ; goes in x,0,><
  63. Const popupminwidth = 14 ; goes in x,0,><
  64. Const popuplineactive = 15 ; line?
  65.  
  66. Global popuplinedr = 55 ; popup dark line
  67. Global popuplinedg = 55
  68. Global popuplinedb = 55
  69. Global popuplinelr = 200 ; popup light line
  70. Global popuplinelg = 200
  71. Global popuplinelb = 200
  72.  
  73. Global popupcolorr = 150 ; popup surface color
  74. Global popupcolorg = 150
  75. Global popupcolorb = 150
  76. Global popuprectlr = 200 ; light popup rectangle color
  77. Global popuprectlg = 200
  78. Global popuprectlb = 200
  79. Global popuprectdr = 80 ; dark popup rectange color
  80. Global popuprectdg = 80
  81. Global popuprectdb = 80
  82.  
  83. ; Setup popup and sublevels
  84. insertpopupitem(0,0,"Load",1)
  85. insertpopupitem(0,1,"Save",2)
  86. insertpopupline(0,2,3) ; Insert line
  87. insertpopupitem(0,3,"Cut",4)
  88. insertpopupitem(0,4,"Copy",5)
  89. insertpopupitem(0,5,"Paste",6)
  90. insertpopupitem(0,6,"Sub",7)
  91. insertpopupitem(1,0,"Yeah",8)
  92. insertpopupitem(1,1,"this",9)
  93. insertpopupitem(1,2,"is a",10)
  94. insertpopupitem(1,3,"submenu",11)
  95. linkitemtosubmenu(0,4,1) ; menu 0 item 4 gets linked to open menu 1
  96. insertpopupitem(2,0,"Yeah",12)
  97. insertpopupitem(2,1,"this",13)
  98. insertpopupitem(2,2,"is a",14)
  99. insertpopupitem(2,3,"submenu",15)
  100. linkitemtosubmenu(0,6,2) ; menu 0 item 6 gets linked to open menu 2
  101.  
  102. ;
  103. main ; popup is called from this function - one call only
  104. End
  105.  
  106. Function main()
  107.  
  108. While we<>$803
  109. we = WaitEvent()
  110. Select we
  111.         Case $101       ;- Key down
  112.         Case $102       ;- Key up
  113.         If EventData() = 1 Then Exit
  114.         Case $103       ;- Key stroke
  115.         Case $201       ;- Mouse down
  116.         Case $202       ;- Mouse up
  117.                 If EventData() = 2 Then
  118.                         q = popupwindow(num,MouseX(),MouseY(),win)
  119.                         If q>0 Then RuntimeError q
  120.                 End If
  121.         Case $203       ;- Mouse move
  122.         Case $204       ;- Mouse wheel
  123.         Case $205       ;- Mouse enter
  124.         Case $206       ;- Mouse leave
  125.         Case $401       ;- Gadget action
  126.         Case $801       ;- Window move 
  127.         Case $802       ;- Window size
  128.         Case $803       ;- Window close
  129.         Case $804       ;- Window activate
  130.         Case $1001      ;- Menu event
  131.         Case $2001      ;- App suspend 
  132.         Case $2002      ;- App resume          
  133.         Case $2003      ;- App Display Change
  134.         Case $2004 ;- App Begin Modal
  135.         Case $2005 ;- App End Modal
  136.         Case $4001      ;- Timer tick
  137. End Select
  138. Wend
  139. End Function
  140.  
  141. Function popupwindow(num,x,y,parent)
  142.         Local win = CreateWindow("",x,y,popupmaxwidth(num),popupmaxheight(num),parent,32)
  143.         Local can = CreateCanvas(0,0,popupmaxwidth(num),popupmaxheight(num),win)
  144.         drawpopup(num,can)
  145.        
  146.         popupclose = False
  147.  
  148.         Local subwin[5]
  149.         Local subcanvas[5]
  150.         Local subitem[5] ; sub level
  151.         Local subitemmenu[5]
  152.         Local subitemnum[5]
  153.         Local subitemoffsetx[5]
  154.         Local subitemoffsety[5]
  155.         Local subitemactive[5]
  156.         Local subitemorigin[5]
  157.  
  158.         Local subremovetimer = 0
  159.         Local removesubs = False
  160.        
  161.         olditem = -1
  162.         timer = CreateTimer(40)
  163.         While we<>$803
  164.                 we = WaitEvent()
  165.                 Select we
  166.                         Case $101       ;- Key down
  167.                         Case $102       ;- Key up
  168.                         If EventData() = 1 Then Exit
  169.                         Case $103       ;- Key stroke
  170.                         Case $201       ;- Mouse down                  
  171.                                 If currentitem = -1 And subitemactive[0] = False Then we=$803
  172.                         Case $202       ;- Mouse up
  173.                                 If subitemactive[0] = True And subitemnum[0] >-1 Then
  174.                                         If removesubs = False Then
  175.                                                 FreeGadget subwin[0]
  176.                                                 FreeGadget win                                 
  177.                                                 Return popupoutdata(subitem[0],subitemnum[0])
  178.                                         End If
  179.                                 End If
  180.                                 If subitemactive[0] = False Then
  181.                                         Return popupoutdata(num,currentitem)
  182.                                 End If
  183.                         Case $203       ;- Mouse move
  184.                         currentitem =  popupcollision(num,x,y)
  185.                         If subitemactive[0] = True Then subitemnum[0] = popupcollision(subitem[0],subitemoffsetx[0],subitemoffsety[0])
  186.                         If subitemactive[0] = True Then drawpopup(subitem[0],subcanvas[0]) :popupsetitemmousestate(num,subitemorigin[0],True) :drawpopup(num,can)
  187.                         If subitemactive[0] = True And currentitem <> currentsub And subitemnum[0] = -1 Then currentitem = -1          
  188.  
  189.                         DebugLog "Num : " + num + " : " + currentitem + " : " + subitemnum[0]
  190.                         ;If  currentitem <> subitemorigin[0] And subitemnum[0] = 0 And subitemactive[0] = True Then
  191.                         If subitemnum[0] = -1 And subitemactive[0] = True  Then                
  192.                                 If  (Not currentitem = subitemorigin[0])
  193.                                                 If removesubs = False Then
  194.                                                         subremovetimer = MilliSecs() + 400
  195.                                                         removesubs = True
  196.                                                         subitemactive[0] = False
  197.                                                 End If
  198.                                 End If
  199.                         End If
  200.                         ;
  201.                         If currentitem >-1
  202.                                 If olditem <> currentitem Then
  203.                                         If subitemactive[0] = False Then drawpopup(num,can)
  204.                                         ex = drawpopupsubitem(num,currentitem,can)
  205.                                         If ex>-1 And ex<> num Then
  206.                                                 currentsub = currentitem
  207.                                                 If subitemactive[0] = False Then
  208.                                                         If removesubs = True Then
  209.                                                                 FreeGadget subwin[0]
  210.                                                         End If
  211.                                                         removesubs = False
  212.                                                         subwin[0] = subpopupwindow(ex,x+popupmaxwidth(num),y+currentitem*popupfontheight,win)
  213.                                                         subcanvas[0] = popuppoint(1)                                                   
  214.                                                         subitem[0] = ex
  215.                                                         ;subitemmenu[0]
  216.                                                         subitemoffsetx[0] = x+popupmaxwidth(num)
  217.                                                         subitemoffsety[0] = y+currentitem*popupfontheight
  218.                                                         subitemactive[0] = True
  219.                                                         subitemorigin[0] = currentitem
  220.                                                         subitemnum[0] = 0 ; which level
  221.                                                         olditem = currentitem
  222.                                                 End If
  223.                                         End If
  224.                                 End If
  225.                         End If
  226.                         Case $204       ;- Mouse wheel
  227.                         Case $205       ;- Mouse enter
  228.                         currentitem=0
  229.                                                
  230.                         Case $206       ;- Mouse leave
  231.                                 popupmouseleave(num)
  232.                                 drawpopup(num,can)
  233.                                 currentitem = -1
  234.                         Case $401       ;- Gadget action
  235.                         Case $801       ;- Window move         
  236.                                 popupclosegroup()
  237.                         Case $802       ;- Window size
  238.                         Case $803       ;- Window close
  239.                         Case $804       ;- Window activate
  240.                                 popupclosegroup()              
  241.                         Case $1001      ;- Menu event
  242.                         Case $2001      ;- App suspend 
  243.                         Case $2002      ;- App resume          
  244.                         Case $2003      ;- App Display Change
  245.                         Case $2004 ;- App Begin Modal
  246.                         Case $2005 ;- App End Modal
  247.                         Case $4001      ;- Timer tick
  248.                         If popupclose = True Then we=$803
  249.                        
  250.                         If subremovetimer < MilliSecs() And removesubs = True Then                             
  251.                                 FreeGadget subwin[0] : subitemactive[0] = False : olditem = -1
  252.                                 removesubs = False
  253.                         End If
  254.  
  255.                 End Select
  256.         Wend
  257.         FreeGadget win
  258. End Function
  259.  
  260. Function linkitemtosubmenu(parent,id,child) ; menu , item, >open menu<
  261.         popupdata(parent,id,popuppointer) = child
  262. End Function
  263. Function insertpopupitem(num,id,newtext$,outid,child=-1)
  264.         popupdata(num,id,popupactive) = True
  265.         popupdata(num,id,popupisinitiated)  = True
  266.         popupdata(num,id,popupminwidth) = 64
  267.         popupdata(num,id,popuptext) = newtext$
  268.         popupdata(num,id,popuppointer) = -1
  269.         popupData(num,id,popupoutdata) = outid
  270.         popupdata(num,id,popuplineactive) = False
  271.         If child <> -1 Then
  272.                 popupdata(num,id,popuppointer)  = child ; open another popup menu
  273.         End If
  274. End Function
  275. Function insertpopupline(num,id,outid)
  276.         popupdata(num,id,popupactive) = True
  277.         popupdata(num,id,popupisinitiated)  = True
  278.         popupdata(num,id,popupminwidth) = 64
  279.         popupdata(num,id,popuptext) = " "
  280.         popupdata(num,id,popuppointer) = -1
  281.         popupData(num,id,popupoutdata) = outid
  282.         popupdata(num,id,popuplineactive) = True
  283. End Function
  284.  
  285. Function deletepopupitem(num,id)
  286.         popupdata(num,id,popupactive) = False
  287. End Function
  288.  
  289. Function subpopupwindow(num,x,y,parent)
  290.         Local win = CreateWindow("",x,y,popupmaxwidth(num),popupmaxheight(num),parent,32)
  291.         Local can = CreateCanvas(0,0,popupmaxwidth(num),popupmaxheight(num),win)
  292.         drawpopup(num,can)
  293.         popuppoint(0) = win
  294.         popuppoint(1) = can
  295.         Return win
  296. End Function
  297. Function getpopupnumitems(num)
  298.         If popupisinitiated(num) = False Then Return
  299.         cnt=0
  300.         For i=0 To numpopupitems
  301.                 If popupactive(num,i) = True Then cnt=cnt+1
  302.         Next
  303.         Return cnt
  304. End Function
  305. Function getpopuptext$(num,id) ; get
  306.         If popupdata(num,id,popupactive) = True Then
  307.                 Return popupdata(num,id,popuptext)
  308.         End If
  309. End Function
  310. Function popuptext(num,id,newtext$) ; set
  311.         popupdata(num,id,popuptext) = newtext$
  312. End Function
  313.  
  314. Function popupactive(num,id)
  315.         ; returns if a popup menu item is active
  316.         If popupdata(num,id,popupisinitiated) = True Then Return True
  317.         Return False
  318. End Function
  319. Function popuphassubmenu(num,id)
  320.         If popupactive(num,id) = False Then Return False
  321.         If popupdata(num,id,popuppointer) > -1 Then Return True
  322.         Return False
  323. End Function
  324. Function popupitemisline(num,id)
  325.         If popupactive(num,id) = False Then Return
  326.         If popupdata(num,id,popuplineactive) = True Then Return True
  327. End Function
  328. Function popupcollision(num,x,y)
  329.         w = popupmaxwidth(num)
  330.         h = popupmaxheight(num)
  331.         n = getpopupnumitems(num)
  332.         y=y+10
  333.         If RectsOverlap(MouseX(),MouseY(),1,1,x,y,w-1,h-1) = True Then
  334.                 x2 = MouseX()-x
  335.                 y2 = MouseY()-y
  336.                 y3 = y2/popupfontheight
  337.                 popupsetitemmousestate(num,y3,True)
  338.                 Return y3
  339.         End If
  340.         Return -1
  341. End Function
  342. Function popupmouseleave(num)
  343.         popupsetitemmousestate(num,0,False)
  344. End Function
  345. Function popupsetitemmousestate(num,id,st)
  346.         If id<0 Then Return
  347.         ;erase prev ; optimize!
  348.         For i=0 To numpopupitems
  349.                 popupdata(num,i,popupmouseontop) = False
  350.         Next
  351.         ;
  352.         popupdata(num,id,popupmouseontop) = st
  353. End Function
  354. Function popupmouseitemcollision(num,id)
  355.         If Int(popupdata(num,id,popupmouseontop)) = True Then Return True
  356.         Return False
  357. End Function
  358. Function popupisinitiated(num)
  359.         If popupdata(num,0,popupisinitiated) = True Then Return True
  360. End Function
  361. Function popupclosegroup()
  362.         popupclose = True
  363. End Function
  364. Function popupoutdata(num,id)
  365.         Return popupdata(num,id,popupoutdata)
  366. End Function
  367.  
  368. Function drawpopup(num,can) ; visuals
  369.         SetBuffer CanvasBuffer(can)
  370.         ClsColor popupcolorr,popupcolorg,popupcolorb   
  371.         Cls    
  372.         x=0
  373.         y=0
  374.         drawpopuprect(x,y,popupmaxwidth(num),popupmaxheight(num))
  375.         fh = FontHeight()
  376.         For i=0 To numpopupitems
  377.                 If popupdata(num,i,popupactive) = True Then
  378.                         If popupitemisline(num,i) = True Then
  379.                                 drawpopupln(x,y,popupmaxwidth(num))
  380.                         Else
  381.                                 drawpopupline(num,x,y,popupdata(num,i,popuptext),popupmouseitemcollision(num,i)) ; draw line non selected
  382.                                 If popuphassubmenu(num,i) = True Then drawpopuparrow(x+popupmaxwidth(num)-10,y)
  383.                         End If
  384.                         y=y+fh
  385.                 End If
  386.         Next
  387.         FlipCanvas(can)
  388. End Function
  389. Function drawpopuprect(x,y,w,h)
  390.         ;       Color 0,0,0 ; Oldskool
  391.         ;       Rect x,y,w,h,False
  392.         ;       Color 200,200,200
  393.         ;       x=x+1 : w=w-2
  394.         ;       y=y+1 : h=h-2
  395.         ;       Rect x,y,w,h,False
  396.        
  397.         Color popuprectdr,popuprectdg,popuprectdb  ; top to right, top right to bottom (outer)
  398.         Line x,y,x+w,y
  399.         Line x,y,x,y+h
  400.         Color 200,200,200 ; top to right, top right to bottom (inner)
  401.         x=x+1 : w=w-2 : y=y+1 : h=h-2
  402.         Line x,y,x+w,y
  403.         Line x,y,x,y+h
  404.         Color 0,0,0 ; bottom right to top, bottom right to left (outer)
  405.         Line x+w,y+h,x+w,y
  406.         Line x+w,y+h,x,y+h
  407.         Color popuprectdr,popuprectdg,popuprectdb ; bottom right to top, bottom right to left (inner)
  408.         y=y-1 : x=x-1
  409.         Line x+w,y+h,x+w,y-1
  410.         Line x+w,y+h,x+1,y+h
  411. End Function
  412. Function drawpopupline(num,x,y,newtext$,state) ; visuals
  413.         If state = True Then
  414.                 Color 50,50,50
  415.                 Rect x,y+10,popupmaxwidth(num),FontHeight(),True
  416.         End If
  417.         Color 255,255,255
  418.         ;x = x + popupmaxwidth(num)/2
  419.        
  420.         Text x+10,y+10,newtext$,0,0
  421.        
  422. End Function
  423. Function drawpopupln(x,y,w)
  424.         y = y + 10 + (popuplineheight()/2)
  425.         x=x+3
  426.         w=w-9
  427.         Color popuplinedr,popuplinedg,popuplinedb
  428.         Line x,y,x+w,y
  429.         Color popuplinelr,popuplinelg,popuplinelb
  430.         y=y+1
  431.         Line x,y,x+w,y
  432. End Function
  433. Function drawpopupsubitem(num,id,can) ; temp
  434.         If popupdata(num,id,popuppointer) > -1 Then Return popupdata(num,id,popuppointer)
  435.         Return -1
  436. End Function
  437. Function drawpopuparrow(x,y)
  438.         ; Needs buffering!!
  439.         y=y+(popuplineheight())+3
  440.         Color 0,0,0
  441.         cnt=cnt+1
  442.         y2# = 7
  443.         Line x,y-4,x,y+4
  444.         For x1=x To x+4
  445.                 Line x1,y,x1,y+(y2/2)
  446.                 Line x1,y,x1,y-(y2/2)
  447.                 y2#=y2#-1.7
  448.         Next
  449. End Function
  450.  
  451. Function popupmaxwidth(num)
  452.         w=0
  453.         For i=0 To numpopupitems
  454.                 If popupactive(num,i) = True Then
  455.                         If w < popupitemwidth(num,i) Then w = popupitemwidth(num,i)                    
  456.                 End If
  457.         Next
  458.         w2 = popupminwidth(num)
  459.         If w2 > w Then Return w2 + 20
  460.         Return w + 20
  461. End Function
  462. Function popupmaxheight(num)
  463.         Return (getpopupnumitems(num) * popupfontheight)+20
  464. End Function
  465. Function popupminwidth(num)
  466.         If popupisinitiated(num) = False Then Return False
  467.         Return popupdata(num,0,popupminwidth)
  468. End Function
  469. Function popupitemwidth(num,id)
  470.         If popupactive(num,id) = True Then             
  471.                 Return (Len(getpopuptext(num,id))) * popupfontwidth
  472.         End If
  473. End Function
  474. Function popupitemheight(num,id)
  475.         Return popupfontheight
  476. End Function
  477. Function popuplineheight()
  478.         Return popupfontheight
  479. End Function


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal