Für eine Touch-Anwendung habe ich mir gerade ein PopupImageMenu auf Canvas-Basis gebastelt (Hintergrund: Kein Rechtsklick und pfriemelige Minimenüs, die man nicht mal mit einem Stift richtig trifft. Da es ein Hybrid-Tablet/Laptop ist, will ich auch nicht die Anzeigeeinstellungen auf Rentner-Modus stellen. Daher, für die 2 Anwendungen, die ich für dne Touch/Tablet/Finger Modus entwickle, eigene, große GUI-Elemente)
edit: Modularisiert und Code ein wenig aufgeräumt (gibt aber trotzdem sicher noch einiges zu verbessern). Man kann jetzt mehrere, verschiedene Menüs erstellen.
Include:
Code: Alles auswählen
EnableExplicit
DeclareModule CanvasPopupMenu
#Event_PopupMenu = #PB_Event_FirstCustomValue + 1 ;Bei Kollision mit anderen Custom-Events anpassen!
#EventType_EntrySelected = #PB_EventType_FirstCustomValue + 1 ;Bei Kollision mit anderen Custom-Events anpassen!
Declare Create(menuID, entryHeight.i, backgroundColor=0, fontID=#PB_Default) ;Gibt #False zurück, falls Menü schon existiert. Anderfalls #True
Declare AddMenuItem(menuID, imageID, text.s, textcolor=$FFFFFF) ; Gibt ID des erstellen Eintrags zurück: entryID.i = AddCanvasPopupMenuEntry(...)
Declare Display(menuID, parentWindow, x=0, y=0) ; Wie PB-Befehl: DisplayPopupMenu()
Declare CanvasEventMenu() ;Äquivalent zu EventMenu(), gibt die ID des Menus zurück in welchem ein Eintrag gewählt wurde
Declare GetPopupEntryID() ;Gibt die ID des Menu-Eintrags zurück, welcher angeklickt wurde
;(Achtung, anders als PB können mehrere Menüs Einträge mit der gleichen ID haben.
;Bei Verwedung mehrerer Menüs ist unbedingt CanvasEventMenu() vorzuschalten
EndDeclareModule
Module CanvasPopupMenu
Define popupMenuWindowHandle
Define currentPopupWindowHandle ;-1 if no popup is currently open
Structure struct_canvaspopupmenuentry
imageID.i
text.s
textColor.i
EndStructure
Structure struct_canvaspopupmenu
menuID.i
parentWindow.i
fontID.i
backColor.i
entryHeight.i
List entries.struct_canvaspopupmenuentry()
EndStructure
NewList Menus.struct_canvaspopupmenu()
Procedure __closepopup()
Shared popupMenuWindowHandle
Shared currentPopupWindowHandle
currentPopupWindowHandle = -1
CloseWindow(popupMenuWindowHandle)
EndProcedure
Procedure __canvaspopupentry_clicked()
Shared currentPopupWindowHandle
Shared popupMenuWindowHandle
Shared Menus()
Protected entryheight
If currentPopupWindowHandle > -1
ForEach Menus()
If Menus()\menuID = currentPopupWindowHandle
entryheight = Menus()\entryheight
PostEvent(#Event_PopupMenu, EventWindow(), currentPopupWindowHandle, #EventType_EntrySelected, WindowMouseY(popupMenuWindowHandle)/entryheight )
__closepopup()
Break
EndIf
Next
EndIf
EndProcedure
Procedure Create(menuID, entryHeight.i, backgroundColor=0, fontID=#PB_Default)
Shared Menus()
ForEach Menus()
If Menus()\menuID =menuID
ProcedureReturn #False
EndIf
Next
AddElement(Menus())
Menus()\menuID=menuID
Menus()\backColor = backgroundColor
Menus()\fontID = fontID
Menus()\entryHeight = entryHeight
ProcedureReturn #True
EndProcedure
Procedure AddMenuItem(menuID, imageID, text.s, textcolor=$FFFFFF)
Shared Menus()
AddElement(Menus()\entries())
With Menus()\entries()
\textColor = textcolor
\imageID = imageID
\text = text
EndWith
ProcedureReturn ListSize(Menus()\entries()) - 1
EndProcedure
Procedure Display(menuID, parentWindow, x=0, y=0)
Shared popupMenuWindowHandle
Shared currentPopupWindowHandle
Protected c, numof_entries, ypos, maxtextwidth
Shared Menus()
ForEach Menus()
If Menus()\menuID = menuID
popupMenuWindowHandle=OpenWindow(#PB_Any, WindowX(parentwindow, #PB_Window_InnerCoordinate)+WindowMouseX(parentwindow)+x,WindowY(parentwindow, #PB_Window_InnerCoordinate)+WindowMouseY(parentwindow)+y, 0,0,"POPUP",#PB_Window_BorderLess, WindowID(parentwindow))
currentPopupWindowHandle = menuID
BindEvent(#PB_Event_DeactivateWindow, @__closepopup(), popupMenuWindowHandle)
c=CanvasGadget(#PB_Any, 0, 0, 2000, 2000)
StartDrawing(CanvasOutput(c))
Box(0, 0, 2000,2000, Menus()\backcolor)
If Menus()\fontid <> #PB_Default
DrawingFont(Menus()\fontid)
EndIf
DrawingMode(#PB_2DDrawing_Transparent)
ForEach Menus()\entries()
numof_entries = numof_entries + 1
With Menus()\entries()
DrawImage(\imageID, 0, ypos, Menus()\entryheight, Menus()\entryheight)
DrawText(Menus()\entryheight+5, ypos + Menus()\entryheight/2 - TextHeight(\text)/2, \text,\textColor)
If TextWidth(\text)>maxtextwidth
maxtextwidth = TextWidth(\text)
EndIf
EndWith
ypos = ypos + Menus()\entryheight
Next
StopDrawing()
BindEvent(#PB_Event_Gadget, @__canvaspopupentry_clicked(), popupMenuWindowHandle, c, #PB_EventType_LeftClick )
ResizeWindow(popupMenuWindowHandle, #PB_Ignore, #PB_Ignore, Menus()\entryheight+10+maxtextwidth, numof_entries * Menus()\entryheight)
ResizeGadget(c, #PB_Ignore, #PB_Ignore, Menus()\entryheight+10+maxtextwidth, numof_entries * Menus()\entryheight)
Break
EndIf
Next
EndProcedure
Procedure GetPopupEntryID()
ProcedureReturn EventData()
EndProcedure
Procedure CanvasEventMenu()
ProcedureReturn EventGadget()
EndProcedure
EndModule
DisableExplicit
Beispiel:
Code: Alles auswählen
;-
;-
;- BEGIN EXAMPLE
;-
If #PB_Compiler_IsMainFile = #True
;Erstelle einige Testbilder als Icons für die Menüeinträge
CreateImage(0, 50, 50):StartDrawing(ImageOutput(0)):Circle(25,25,24,$FF6600):StopDrawing()
CreateImage(1, 50, 50):StartDrawing(ImageOutput(1)):Circle(25,25,24,$0000FF):StopDrawing()
CreateImage(2, 50, 50):StartDrawing(ImageOutput(2)):Circle(25,25,24,$00FF00):StopDrawing()
CreateImage(3, 50, 50):StartDrawing(ImageOutput(3)):Circle(25,25,24,$FFFFFF):StopDrawing()
;Öffne Testfenster mit Button
#Win = 0
OpenWindow(#Win, 0, 0, 400, 400, "Canvas Popup Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ButtonGadget(0, 10, 10, 150, 40, "TEST")
ButtonGadget(1, 10, 110, 150, 40, "TEST2")
;Lade Fonts für das CanvasMenu
LoadFont(0, "Times New Roman", 14, #PB_Font_Italic)
LoadFont(1, "Wingdings", 16)
;Erstelle Popup-Menu ("Equivalent" zu CreatePopupImageMenu())
;CanvasPopupMenu::Create(MenuID, Größe der Icons (zugleich die Höhe ein Einträge), [Hintergrundfarbe des Menüs], [Font])
CanvasPopupMenu::Create(1, 50, $FFcc99, FontID(0))
;Füge Einträge hinzu (in der Reihenfolge des Codes. Hier gibt es keine IDs zu vergeben. Die IDs werden von der Funktion zurückgegeben)
;CanvasPopupMenu::AddMenuItem(Eltern-Menu, ImageID für das Icon, Text, Textfarbe)
CanvasPopupMenu::AddMenuItem(1, ImageID(1), "Rot", 0)
CanvasPopupMenu::AddMenuItem(1, ImageID(0), "Blau blau blau blau........lj 8u9 gg7 vbnun97", $FF00FF)
CanvasPopupMenu::AddMenuItem(1, ImageID(2), "Grün", $009900)
myEntryID = CanvasPopupMenu::AddMenuItem(1, ImageID(3), "Klick hier und lass dich vom Debugger überraschen", $00FFFF) ;returns ID
;Erstelle zweites Menu
CanvasPopupMenu::Create(2, 30, $FFcc99, FontID(1))
CanvasPopupMenu::AddMenuItem(2, ImageID(1), "ABC", 0)
CanvasPopupMenu::AddMenuItem(2, ImageID(0), "47r", $990000)
Repeat
e=WaitWindowEvent()
If e=#PB_Event_Gadget
If EventGadget()=0
;Ähnlich wie in PB: DisplayPopupMenu(menuID, parentWindow, [x, y])
CanvasPopupMenu::Display(1, #Win)
ElseIf EventGadget()=1
CanvasPopupMenu::Display(2, #Win)
EndIf
EndIf
If e=CanvasPopupMenu::#Event_PopupMenu ;Wenn unser Custom-Event auftritt...
Debug "EventMenu: "+CanvasPopupMenu::CanvasEventMenu()
Debug "EntryID: "+CanvasPopupMenu::GetPopupEntryID()
Debug ""
If CanvasPopupMenu::CanvasEventMenu() = 1 And CanvasPopupMenu::GetPopupEntryID() = myEntryID
Debug ">>>"
Debug ">>> ÜBERRASCHUNG!! :)"
Debug ">>>"
EndIf
EndIf
Until e=#PB_Event_CloseWindow
EndIf