Code archives/BlitzPlus Gui/Popup menu
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Right mouse to activate pop up menu. | |||||
; ; Blitz + Native Popup menu, No dll or userlib required ; ; (c) R.v.Etten / Nebula in 2004 ; ; Currently minor visuals are added and the submenus only go one level deep. The menu's might also sometimes be slightly ; jitterisch. ; ; Functions Draw... can be adjusted to modify the visual apearance of the popup menu ;Todo : ; ; Display key Shotcuts ; Modularize popup control structure ; Put popup collision in timer ; Large menu scrolling (scrollbar?) ; Auto adjust popup layout to size (screen) ; Blanked out text (inactive / disable / enable) ; More user level control function ; More sub menu levels ; Update popup output handling to contents ; Better interactive control ; Inline images and user controls ; Easy user level color control ; ;Todo maybe : ; ; Menu resizing animation ; Skins and oval/round popup menus ; Sound effects ; Fullscreen version ; Menu mode ; Inline animations ; Load data from Ini file Global winwidth = 640 Global winheight = 480 Global win = CreateWindow("Window",ClientWidth(Desktop())/2-winwidth/2,ClientHeight(Desktop())/2-winheight/2,winwidth,winheight,Desktop(),1+8) Global popupfontwidth = 8 Global popupfontheight = 13 Global popupclose Const numpopupmenus = 4 Const numpopupitems = 99 Dim popupdata$(numpopupmenus,numpopupitems,22) Dim popuppoint(1) ; win,canvas switch Const popupactive = 0 Const popuptext = 1 Const popupwidth = 2 Const popupheight = 3 Const popupx = 4 Const popupy = 5 Const popupnumitems = 6 Const popuppointer = 7 ; point to another popup menu Const popupenabled = 8 Const popupline = 9 Const popupmouseontop = 10 Const popupoutdata = 11 Const popupisinitiated = 12 ; goes in x,0,>< Const popupmenuwidth = 13 ; goes in x,0,>< Const popupminwidth = 14 ; goes in x,0,>< Const popuplineactive = 15 ; line? Global popuplinedr = 55 ; popup dark line Global popuplinedg = 55 Global popuplinedb = 55 Global popuplinelr = 200 ; popup light line Global popuplinelg = 200 Global popuplinelb = 200 Global popupcolorr = 150 ; popup surface color Global popupcolorg = 150 Global popupcolorb = 150 Global popuprectlr = 200 ; light popup rectangle color Global popuprectlg = 200 Global popuprectlb = 200 Global popuprectdr = 80 ; dark popup rectange color Global popuprectdg = 80 Global popuprectdb = 80 ; Setup popup and sublevels insertpopupitem(0,0,"Load",1) insertpopupitem(0,1,"Save",2) insertpopupline(0,2,3) ; Insert line insertpopupitem(0,3,"Cut",4) insertpopupitem(0,4,"Copy",5) insertpopupitem(0,5,"Paste",6) insertpopupitem(0,6,"Sub",7) insertpopupitem(1,0,"Yeah",8) insertpopupitem(1,1,"this",9) insertpopupitem(1,2,"is a",10) insertpopupitem(1,3,"submenu",11) linkitemtosubmenu(0,4,1) ; menu 0 item 4 gets linked to open menu 1 insertpopupitem(2,0,"Yeah",12) insertpopupitem(2,1,"this",13) insertpopupitem(2,2,"is a",14) insertpopupitem(2,3,"submenu",15) linkitemtosubmenu(0,6,2) ; menu 0 item 6 gets linked to open menu 2 ; main ; popup is called from this function - one call only End Function main() While we<>$803 we = WaitEvent() Select we Case $101 ;- Key down Case $102 ;- Key up If EventData() = 1 Then Exit Case $103 ;- Key stroke Case $201 ;- Mouse down Case $202 ;- Mouse up If EventData() = 2 Then q = popupwindow(num,MouseX(),MouseY(),win) If q>0 Then RuntimeError q End If Case $203 ;- Mouse move Case $204 ;- Mouse wheel Case $205 ;- Mouse enter Case $206 ;- Mouse leave Case $401 ;- Gadget action Case $801 ;- Window move Case $802 ;- Window size Case $803 ;- Window close Case $804 ;- Window activate Case $1001 ;- Menu event Case $2001 ;- App suspend Case $2002 ;- App resume Case $2003 ;- App Display Change Case $2004 ;- App Begin Modal Case $2005 ;- App End Modal Case $4001 ;- Timer tick End Select Wend End Function Function popupwindow(num,x,y,parent) Local win = CreateWindow("",x,y,popupmaxwidth(num),popupmaxheight(num),parent,32) Local can = CreateCanvas(0,0,popupmaxwidth(num),popupmaxheight(num),win) drawpopup(num,can) popupclose = False Local subwin[5] Local subcanvas[5] Local subitem[5] ; sub level Local subitemmenu[5] Local subitemnum[5] Local subitemoffsetx[5] Local subitemoffsety[5] Local subitemactive[5] Local subitemorigin[5] Local subremovetimer = 0 Local removesubs = False olditem = -1 timer = CreateTimer(40) While we<>$803 we = WaitEvent() Select we Case $101 ;- Key down Case $102 ;- Key up If EventData() = 1 Then Exit Case $103 ;- Key stroke Case $201 ;- Mouse down If currentitem = -1 And subitemactive[0] = False Then we=$803 Case $202 ;- Mouse up If subitemactive[0] = True And subitemnum[0] >-1 Then If removesubs = False Then FreeGadget subwin[0] FreeGadget win Return popupoutdata(subitem[0],subitemnum[0]) End If End If If subitemactive[0] = False Then Return popupoutdata(num,currentitem) End If Case $203 ;- Mouse move currentitem = popupcollision(num,x,y) If subitemactive[0] = True Then subitemnum[0] = popupcollision(subitem[0],subitemoffsetx[0],subitemoffsety[0]) If subitemactive[0] = True Then drawpopup(subitem[0],subcanvas[0]) :popupsetitemmousestate(num,subitemorigin[0],True) :drawpopup(num,can) If subitemactive[0] = True And currentitem <> currentsub And subitemnum[0] = -1 Then currentitem = -1 DebugLog "Num : " + num + " : " + currentitem + " : " + subitemnum[0] ;If currentitem <> subitemorigin[0] And subitemnum[0] = 0 And subitemactive[0] = True Then If subitemnum[0] = -1 And subitemactive[0] = True Then If (Not currentitem = subitemorigin[0]) If removesubs = False Then subremovetimer = MilliSecs() + 400 removesubs = True subitemactive[0] = False End If End If End If ; If currentitem >-1 If olditem <> currentitem Then If subitemactive[0] = False Then drawpopup(num,can) ex = drawpopupsubitem(num,currentitem,can) If ex>-1 And ex<> num Then currentsub = currentitem If subitemactive[0] = False Then If removesubs = True Then FreeGadget subwin[0] End If removesubs = False subwin[0] = subpopupwindow(ex,x+popupmaxwidth(num),y+currentitem*popupfontheight,win) subcanvas[0] = popuppoint(1) subitem[0] = ex ;subitemmenu[0] subitemoffsetx[0] = x+popupmaxwidth(num) subitemoffsety[0] = y+currentitem*popupfontheight subitemactive[0] = True subitemorigin[0] = currentitem subitemnum[0] = 0 ; which level olditem = currentitem End If End If End If End If Case $204 ;- Mouse wheel Case $205 ;- Mouse enter currentitem=0 Case $206 ;- Mouse leave popupmouseleave(num) drawpopup(num,can) currentitem = -1 Case $401 ;- Gadget action Case $801 ;- Window move popupclosegroup() Case $802 ;- Window size Case $803 ;- Window close Case $804 ;- Window activate popupclosegroup() Case $1001 ;- Menu event Case $2001 ;- App suspend Case $2002 ;- App resume Case $2003 ;- App Display Change Case $2004 ;- App Begin Modal Case $2005 ;- App End Modal Case $4001 ;- Timer tick If popupclose = True Then we=$803 If subremovetimer < MilliSecs() And removesubs = True Then FreeGadget subwin[0] : subitemactive[0] = False : olditem = -1 removesubs = False End If End Select Wend FreeGadget win End Function Function linkitemtosubmenu(parent,id,child) ; menu , item, >open menu< popupdata(parent,id,popuppointer) = child End Function Function insertpopupitem(num,id,newtext$,outid,child=-1) popupdata(num,id,popupactive) = True popupdata(num,id,popupisinitiated) = True popupdata(num,id,popupminwidth) = 64 popupdata(num,id,popuptext) = newtext$ popupdata(num,id,popuppointer) = -1 popupData(num,id,popupoutdata) = outid popupdata(num,id,popuplineactive) = False If child <> -1 Then popupdata(num,id,popuppointer) = child ; open another popup menu End If End Function Function insertpopupline(num,id,outid) popupdata(num,id,popupactive) = True popupdata(num,id,popupisinitiated) = True popupdata(num,id,popupminwidth) = 64 popupdata(num,id,popuptext) = " " popupdata(num,id,popuppointer) = -1 popupData(num,id,popupoutdata) = outid popupdata(num,id,popuplineactive) = True End Function Function deletepopupitem(num,id) popupdata(num,id,popupactive) = False End Function Function subpopupwindow(num,x,y,parent) Local win = CreateWindow("",x,y,popupmaxwidth(num),popupmaxheight(num),parent,32) Local can = CreateCanvas(0,0,popupmaxwidth(num),popupmaxheight(num),win) drawpopup(num,can) popuppoint(0) = win popuppoint(1) = can Return win End Function Function getpopupnumitems(num) If popupisinitiated(num) = False Then Return cnt=0 For i=0 To numpopupitems If popupactive(num,i) = True Then cnt=cnt+1 Next Return cnt End Function Function getpopuptext$(num,id) ; get If popupdata(num,id,popupactive) = True Then Return popupdata(num,id,popuptext) End If End Function Function popuptext(num,id,newtext$) ; set popupdata(num,id,popuptext) = newtext$ End Function Function popupactive(num,id) ; returns if a popup menu item is active If popupdata(num,id,popupisinitiated) = True Then Return True Return False End Function Function popuphassubmenu(num,id) If popupactive(num,id) = False Then Return False If popupdata(num,id,popuppointer) > -1 Then Return True Return False End Function Function popupitemisline(num,id) If popupactive(num,id) = False Then Return If popupdata(num,id,popuplineactive) = True Then Return True End Function Function popupcollision(num,x,y) w = popupmaxwidth(num) h = popupmaxheight(num) n = getpopupnumitems(num) y=y+10 If RectsOverlap(MouseX(),MouseY(),1,1,x,y,w-1,h-1) = True Then x2 = MouseX()-x y2 = MouseY()-y y3 = y2/popupfontheight popupsetitemmousestate(num,y3,True) Return y3 End If Return -1 End Function Function popupmouseleave(num) popupsetitemmousestate(num,0,False) End Function Function popupsetitemmousestate(num,id,st) If id<0 Then Return ;erase prev ; optimize! For i=0 To numpopupitems popupdata(num,i,popupmouseontop) = False Next ; popupdata(num,id,popupmouseontop) = st End Function Function popupmouseitemcollision(num,id) If Int(popupdata(num,id,popupmouseontop)) = True Then Return True Return False End Function Function popupisinitiated(num) If popupdata(num,0,popupisinitiated) = True Then Return True End Function Function popupclosegroup() popupclose = True End Function Function popupoutdata(num,id) Return popupdata(num,id,popupoutdata) End Function Function drawpopup(num,can) ; visuals SetBuffer CanvasBuffer(can) ClsColor popupcolorr,popupcolorg,popupcolorb Cls x=0 y=0 drawpopuprect(x,y,popupmaxwidth(num),popupmaxheight(num)) fh = FontHeight() For i=0 To numpopupitems If popupdata(num,i,popupactive) = True Then If popupitemisline(num,i) = True Then drawpopupln(x,y,popupmaxwidth(num)) Else drawpopupline(num,x,y,popupdata(num,i,popuptext),popupmouseitemcollision(num,i)) ; draw line non selected If popuphassubmenu(num,i) = True Then drawpopuparrow(x+popupmaxwidth(num)-10,y) End If y=y+fh End If Next FlipCanvas(can) End Function Function drawpopuprect(x,y,w,h) ; Color 0,0,0 ; Oldskool ; Rect x,y,w,h,False ; Color 200,200,200 ; x=x+1 : w=w-2 ; y=y+1 : h=h-2 ; Rect x,y,w,h,False Color popuprectdr,popuprectdg,popuprectdb ; top to right, top right to bottom (outer) Line x,y,x+w,y Line x,y,x,y+h Color 200,200,200 ; top to right, top right to bottom (inner) x=x+1 : w=w-2 : y=y+1 : h=h-2 Line x,y,x+w,y Line x,y,x,y+h Color 0,0,0 ; bottom right to top, bottom right to left (outer) Line x+w,y+h,x+w,y Line x+w,y+h,x,y+h Color popuprectdr,popuprectdg,popuprectdb ; bottom right to top, bottom right to left (inner) y=y-1 : x=x-1 Line x+w,y+h,x+w,y-1 Line x+w,y+h,x+1,y+h End Function Function drawpopupline(num,x,y,newtext$,state) ; visuals If state = True Then Color 50,50,50 Rect x,y+10,popupmaxwidth(num),FontHeight(),True End If Color 255,255,255 ;x = x + popupmaxwidth(num)/2 Text x+10,y+10,newtext$,0,0 End Function Function drawpopupln(x,y,w) y = y + 10 + (popuplineheight()/2) x=x+3 w=w-9 Color popuplinedr,popuplinedg,popuplinedb Line x,y,x+w,y Color popuplinelr,popuplinelg,popuplinelb y=y+1 Line x,y,x+w,y End Function Function drawpopupsubitem(num,id,can) ; temp If popupdata(num,id,popuppointer) > -1 Then Return popupdata(num,id,popuppointer) Return -1 End Function Function drawpopuparrow(x,y) ; Needs buffering!! y=y+(popuplineheight())+3 Color 0,0,0 cnt=cnt+1 y2# = 7 Line x,y-4,x,y+4 For x1=x To x+4 Line x1,y,x1,y+(y2/2) Line x1,y,x1,y-(y2/2) y2#=y2#-1.7 Next End Function Function popupmaxwidth(num) w=0 For i=0 To numpopupitems If popupactive(num,i) = True Then If w < popupitemwidth(num,i) Then w = popupitemwidth(num,i) End If Next w2 = popupminwidth(num) If w2 > w Then Return w2 + 20 Return w + 20 End Function Function popupmaxheight(num) Return (getpopupnumitems(num) * popupfontheight)+20 End Function Function popupminwidth(num) If popupisinitiated(num) = False Then Return False Return popupdata(num,0,popupminwidth) End Function Function popupitemwidth(num,id) If popupactive(num,id) = True Then Return (Len(getpopuptext(num,id))) * popupfontwidth End If End Function Function popupitemheight(num,id) Return popupfontheight End Function Function popuplineheight() Return popupfontheight End Function |
Comments
None.
Code Archives Forum