Question about popup menu

Just starting out? Need help? Post your questions and find answers here.
wawavoun
User
User
Posts: 38
Joined: Fri Oct 18, 2019 4:49 pm

Question about popup menu

Post by wawavoun »

Hello,

Into a canvas gadget (canvas_0) I try to use a popup menu.

My code look like this :

Code: Select all

blablabla...
;
If EventType=#PB_EventType_RightClick
    ;
    ; Ouvre le menu contextuel dans le canvas_0 si une ligne ou un arc est selectionné
    ;
    If (DataTreeItem >= 3 + nbpoint And DataTreeItem <= 2 + nbpoint + NbLig) Or (DataTreeItem >= 4 + nbpoint + NbLig And DataTreeItem <= 3 + nbpoint + NbLig + NbArc)   
      If CreatePopupMenu(1)      
        MenuItem(1, "Discrétiser")      
        MenuItem(2, "Retourner discrétisation")
        CloseSubMenu()
      EndIf
      DisplayPopupMenu(1, Canvas_0)
    EndIf
    ;
  EndIf
  ;
  If EventType=#PB_Event_Menu
    ;
    Debug EventMenu()
    ;
    Select EventMenu()
        ;
      Case 1
        ;
        Debug "Discrétiser"
        ;
      Case 2
        ;
        Debug "Retourner"
        ;
    EndSelect
    ;
  EndIf
  ;
  If EventType=#PB_EventType_LeftClick
    ;
blablabla....
The line "Debug EventMenu()" give a high number and not the "1" or "2" expected as per the menu creation.
Then of course the Select EventMenu() / EndSelect just below give nothing...

I dont understand where is the problem. Changing Canvas_0 for MainWindow (the window where Canvas_0 is located) into the menu opening instruction give the same result.

Thanks for help.
Philippe
User avatar
mk-soft
Always Here
Always Here
Posts: 6305
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Question about popup menu

Post by mk-soft »

DisplayPopupMenu(1, Canvas_0) -> DisplayPopupMenu(1, WindowID([Your window number]))
Create the PopupMenu only once.

Code: Select all

blablabla...
;

If CreatePopupMenu(1)      
  MenuItem(1, "Discrétiser")      
  MenuItem(2, "Retourner discrétisation")
Else
  Debug "Failed"
EndIf

If EventType=#PB_EventType_RightClick
    ;
    ; Ouvre le menu contextuel dans le canvas_0 si une ligne ou un arc est selectionné
    ;
    If (DataTreeItem >= 3 + nbpoint And DataTreeItem <= 2 + nbpoint + NbLig) Or (DataTreeItem >= 4 + nbpoint + NbLig And DataTreeItem <= 3 + nbpoint + NbLig + NbArc)   
      DisplayPopupMenu(1, WindowID(0))
    EndIf
    ;
  EndIf
  ;
  If EventType=#PB_Event_Menu
    ;
    Debug EventMenu()
    ;
    Select EventMenu()
        ;
      Case 1
        ;
        Debug "Discrétiser"
        ;
      Case 2
        ;
        Debug "Retourner"
        ;
    EndSelect
    ;
  EndIf
  ;
  If EventType=#PB_EventType_LeftClick
    ;
blablabla....
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4984
Joined: Sun Apr 12, 2009 6:27 am

Re: Question about popup menu

Post by RASHAD »

You can use The CanvasGadget() type event as follows

Code: Select all

  If EventType=#PB_Event_Gadget
     ;
    Select EventGadget()
        ;
      Case Canvas_0
        Select EventType()          
          Case #PB_EventType_RightButtonUp   
            DisplayPopupMenu(1, WindowID(0))
        EndSelect
        ;
    EndSelect
    ;
  EndIf
Egypt my love
User avatar
mk-soft
Always Here
Always Here
Posts: 6305
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Question about popup menu

Post by mk-soft »

@RASHAD

the CanvasGadget support right click

Code: Select all

;-TOP

Procedure MouseInRange(Gadget, x, y, Width, Heigth)
  Protected pos_x, pos_y, x2, y2
  pos_x = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
  pos_y = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
  x2 = x + Width
  y2 = y + Heigth
  If pos_x >= x And pos_x < x2
    If pos_y >= y And pos_y < y2
      ProcedureReturn #True
    EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

; ----

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(0)
  dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
  ; Resize Gadgets
  ResizeGadget(0, 5, 5, dx - 10, dy - 10)
EndProcedure

; ----

Procedure Main()
  Protected dx, dy
  
  #WinStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 400, "Test Window", #WinStyle)
    ; MenuBar
    CreateMenu(0, WindowID(0))
    MenuTitle("File")
    
    ; StatusBar
    CreateStatusBar(0, WindowID(0))
    AddStatusBarField(#PB_Ignore)
    
    ; Gadgets
    dx = WindowWidth(0)
    dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
    CanvasGadget(0, 5, 5, dx - 10, dy - 10, #PB_Canvas_Border)
    If StartDrawing(CanvasOutput(0))
      Box(20, 20, 80, 80, #Red)
      StopDrawing()
    EndIf
    
    ; PopUpMenu
    CreatePopupMenu(1)
    MenuItem(1, "Menu 1")
    MenuItem(2, "Menu 2")
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), 0)
    
    ; Main Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case 0
              Break
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            Case 1
              ;
            Case 2
              ;
              
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case 0
              Select EventType()
                Case #PB_EventType_RightClick
                  If MouseInRange(0, 20, 20, 80, 80)
                    DisplayPopupMenu(1, WindowID(0))
                  EndIf
                  
              EndSelect
              
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wawavoun
User
User
Posts: 38
Joined: Fri Oct 18, 2019 4:49 pm

Re: Question about popup menu

Post by wawavoun »

I think I found the problem.

The CanvasGad procedure is called from a MainWindow(event) loop with a CanvasGad(Eventtype()) instruction created by the form designer...

I have to think how to change this... But I want to avoid to made any change "by hand" into the pbf file.

Any idea ?
Thanks.
Philippe
User avatar
mk-soft
Always Here
Always Here
Posts: 6305
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Question about popup menu

Post by mk-soft »

If you use the FormDesigner with event creation. You must have a file where you write the gadget event procedures and select them in the FormDesigner.

Code: Select all

Procedure CanvasGad(EventType)
  Select EventType
    Case #PB_EventType_RightClick
      DisplayPopupMenu(1, WindowID(0))
      
  EndSelect
EndProcedure
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wawavoun
User
User
Posts: 38
Joined: Fri Oct 18, 2019 4:49 pm

Re: Question about popup menu

Post by wawavoun »

That s exactly what I do but the EventMenu item is not into the gadget procedure call parameters...
There is only EventType()...
User avatar
mk-soft
Always Here
Always Here
Posts: 6305
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Question about popup menu

Post by mk-soft »

Just a moment
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 6305
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Question about popup menu

Post by mk-soft »

Example for FormDesigner. For Menu Exit and CanvasGadget I have assigned a procedure in the FormDesigner.
For me, I switch off under Settings -> Form the "New gadget use #PB_Any by default".

MainForm.pbf

Code: Select all

;
; This code is automatically generated by the FormDesigner.
; Manual modification is possible to adjust existing commands, but anything else will be dropped when the code is compiled.
; Event procedures needs to be put in another source file.
;

Enumeration FormWindow
  #MainWindow
EndEnumeration

Enumeration FormGadget
  #Canvas_Gad
EndEnumeration

Enumeration FormMenu
  #MenuItem_Exit
EndEnumeration

Declare DoMenuEvent(Event)
Declare DoCanvasEvent(EventType)

Procedure OpenMainWindow(x = 0, y = 0, width = 600, height = 400)
  OpenWindow(#MainWindow, x, y, width, height, "", #PB_Window_SystemMenu)
  CreateMenu(0, WindowID(#MainWindow))
  MenuTitle("File")
  MenuItem(#MenuItem_Exit, "Exit")
  CanvasGadget(#Canvas_Gad, 10, 10, 580, 380)
EndProcedure

Procedure MainWindow_Events(event)
  Select event
    Case #PB_Event_CloseWindow
      ProcedureReturn #False

    Case #PB_Event_Menu
      Select EventMenu()
        Case #MenuItem_Exit
          DoMenuEvent(EventMenu())
      EndSelect

    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Canvas_Gad
          DoCanvasEvent(EventType())          
      EndSelect
  EndSelect
  ProcedureReturn #True
EndProcedure

Edit: MainFile.pb

Code: Select all


IncludeFile "MainForm.pbf" ; Include the first window definition

Enumeration FormMenu ; <- Same name of form file
  #PopupMenu_1
  #PopupMenu_2
EndEnumeration

; Create PopupMenu
CreatePopupMenu(1)
MenuItem(#PopupMenu_1, "Menu 1")
MenuItem(#PopupMenu_2, "Menu 2")

; The event procedures, as specified in the 'event procedure' property of each gadget
Procedure DoCanvasEvent(EventType)
  Select EventType
    Case #PB_EventType_RightClick
      DisplayPopupMenu(1, WindowID(#MainWindow))
      
  EndSelect
EndProcedure

Procedure DoMenuEvent(EventMenu)
  Select EventMenu
    Case #MenuItem_Exit
      PostEvent(#PB_Event_CloseWindow, #MainWindow, 0)
    
  EndSelect
EndProcedure

Procedure DoPopupMenuEvent(EventMenu)
  Select EventMenu
    Case #PopupMenu_1
      Debug "Popup Menu 1"
      
    Case #PopupMenu_2
      Debug "Popup Menu 2"

  EndSelect
EndProcedure

;- Open Main
OpenMainWindow() ; Open the first window. This procedure name is always 'Open' followed by the window name

If IsWindow(#MainWindow)
  ; The main event loop as usual, the only change is to call the automatically
  ; generated event procedure for each window.
  Repeat
    Event = WaitWindowEvent()
    
    Select EventWindow()
      Case #MainWindow
        If MainWindow_Events(Event) = #False ; This procedure name is always window name followed by '_Events'
          Break
        EndIf
    EndSelect
    
    ; Own Event management
    Select Event
      Case #PB_Event_Menu
        DoPopupMenuEvent(EventMenu())
        
    EndSelect
    
  ForEver
EndIf

But you can also switch off the "Generate event procedures" under Settings -> Form and write the event management yourself. (Which is what many people do)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wawavoun
User
User
Posts: 38
Joined: Fri Oct 18, 2019 4:49 pm

Re: Question about popup menu

Post by wawavoun »

Works well !
Now I have to understand how !!!

Thanks a lot.
Philippe
User avatar
mk-soft
Always Here
Always Here
Posts: 6305
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Question about popup menu

Post by mk-soft »

wawavoun wrote: Sun Aug 06, 2023 3:59 pm Works well !
Now I have to understand how !!!
The general part is almost as described in the PB help for the FormDesigner.
Only for the PopupMenus, the event #PB_Event_Menu must be queried once more in the event loop.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply