#PB_ANY for MenuItem

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

#PB_ANY for MenuItem

Post by Shannara »

It is nice that PB is have gone mostly dynamic since the introduction of #PB_ANY, however, I found out that #PB_ANY does not work for MenuItem, this would be quite helpfull in order to have dynamic menus.
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: #PB_ANY for MenuItem

Post by Randy Walker »

Shannara wrote:It is nice that PB is have gone mostly dynamic since the introduction of #PB_ANY, however, I found out that #PB_ANY does not work for MenuItem, this would be quite helpfull in order to have dynamic menus.
You're more versed with PB than I am, and I don't know what #PB_ANY does just yet, but you've been really helpful to me (and many others I see) so I want to be the first to say "I second this motion" :-)

Besides, this #PB_ANY thing seems to get used a lot so anticipate others would find it useful too. (Twidlling thumbs and holding my breath as the hours count down on Freds return.)
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: #PB_ANY for MenuItem

Post by PB »

> I don't know what #PB_ANY does

It's designed so you don't need to specify constant names for gadgets.
Here's two examples that do the same thing, with and without #PB_Any:

Code: Select all

; WITHOUT #PB_ANY

If OpenWindow(1,300,250,400,200,#PB_Window_SystemMenu,"Window")
  CreateGadgetList(WindowID())
  #button1=1 : ButtonGadget(#button1,50,50,60,25,"1")
  #button2=2 : ButtonGadget(#button2,150,50,60,25,"2")
  Repeat
    ev=WaitWindowEvent()
    If ev=#PB_Event_Gadget
      Select EventGadgetID()
        Case #button1 : Debug "1"
        Case #button2 : Debug "2"
      EndSelect
    EndIf
  Until ev=#PB_EventCloseWindow
EndIf

Code: Select all

; WITH #PB_ANY

If OpenWindow(1,300,250,400,200,#PB_Window_SystemMenu,"Window")
  CreateGadgetList(WindowID())
  b1=ButtonGadget(#PB_Any,50,50,60,25,"1")
  b2=ButtonGadget(#PB_Any,150,50,60,25,"2")
  Repeat
    ev=WaitWindowEvent()
    If ev=#PB_Event_Gadget
      Select EventGadgetID()
        Case b1 : Debug "1"
        Case b2 : Debug "2"
      EndSelect
    EndIf
  Until ev=#PB_EventCloseWindow
EndIf
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: #PB_ANY for MenuItem

Post by Randy Walker »

Code: Select all

; WITHOUT #PB_ANY

  #button1=1 : ButtonGadget(#button1,50,50,60,25,"1")
  #button2=2 : ButtonGadget(#button2,150,50,60,25,"2")
  
; WITH #PB_ANY

  b1=ButtonGadget(#PB_Any,50,50,60,25,"1")
  b2=ButtonGadget(#PB_Any,150,50,60,25,"2")
Perfectly clear... thanks PB

Ok, I see simpler code but no distinct functional advantage, unless b1 and b2 could be replaced with b(1) and b(2) when using MenuItem.

Is #PB_ANY not allowed for MenuItem in both CreateMenu and CreatePopupMenu routines? CreateMenu seems to replace the default "system menu" for a window and I'm thinking PB may not find a popup menu so gummy to work with internally... guessing.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

When you get into high numbers with enumeration or such, the PB program will crash. Also, this is more dynamic, before PB_ANY PB was majorly restrictive.. I mean HUGELY restrictive. Believe or not, for some odd reason the PureVision author still uses enumerations instead of PB_ANY for it's generated code.... I guess some people are not into dynamic code generation :D

Anyways, its quite helpfull for anything to do with database, games, networking, etc. As with anything you do not know the exact number of objects the user would be using.

Anyways, I was suprised Fred havent added this into the menu commands... really weird, actually.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: #PB_ANY for MenuItem

Post by PB »

> I see simpler code but no distinct functional advantage

It means you don't have to declare a million constants if you have a million
gadgets. :) Let's say you have 20 x ButtonGadgets... compare the code:

Code: Select all

; WITH #PB_ANY

Dim gid(20)
If OpenWindow(1,200,150,600,450,#PB_Window_SystemMenu,"Window")
  CreateGadgetList(WindowID())
  For n=1 To 20
    gid(n)=ButtonGadget(#PB_Any,n*20,n*20,30,25,Str(n))
  Next
  Repeat
    ev=WaitWindowEvent()
    If ev=#PB_Event_Gadget
      For n=1 To 20
        If EventGadgetID()=gid(n) : Debug n : Break : EndIf
      Next
    EndIf
  Until ev=#PB_EventCloseWindow
EndIf

Code: Select all

; WITHOUT #PB_ANY

If OpenWindow(1,200,150,600,450,#PB_Window_SystemMenu,"Window")
  CreateGadgetList(WindowID())
  #gid1=1 : n+1 : ButtonGadget(#gid1,n*20,n*20,30,25,Str(n))
  #gid2=2 : n+1 : ButtonGadget(#gid2,n*20,n*20,30,25,Str(n))
  #gid3=3 : n+1 : ButtonGadget(#gid3,n*20,n*20,30,25,Str(n))
  #gid4=4 : n+1 : ButtonGadget(#gid4,n*20,n*20,30,25,Str(n))
  #gid5=5 : n+1 : ButtonGadget(#gid5,n*20,n*20,30,25,Str(n))
  #gid6=6 : n+1 : ButtonGadget(#gid6,n*20,n*20,30,25,Str(n))
  #gid7=7 : n+1 : ButtonGadget(#gid7,n*20,n*20,30,25,Str(n))
  #gid8=8 : n+1 : ButtonGadget(#gid8,n*20,n*20,30,25,Str(n))
  #gid9=9 : n+1 : ButtonGadget(#gid9,n*20,n*20,30,25,Str(n))
  #gid10=10 : n+1 : ButtonGadget(#gid10,n*20,n*20,30,25,Str(n))
  #gid11=11 : n+1 : ButtonGadget(#gid11,n*20,n*20,30,25,Str(n))
  #gid12=12 : n+1 : ButtonGadget(#gid12,n*20,n*20,30,25,Str(n))
  #gid13=13 : n+1 : ButtonGadget(#gid13,n*20,n*20,30,25,Str(n))
  #gid14=14 : n+1 : ButtonGadget(#gid14,n*20,n*20,30,25,Str(n))
  #gid15=15 : n+1 : ButtonGadget(#gid15,n*20,n*20,30,25,Str(n))
  #gid16=16 : n+1 : ButtonGadget(#gid16,n*20,n*20,30,25,Str(n))
  #gid17=17 : n+1 : ButtonGadget(#gid17,n*20,n*20,30,25,Str(n))
  #gid18=18 : n+1 : ButtonGadget(#gid18,n*20,n*20,30,25,Str(n))
  #gid19=19 : n+1 : ButtonGadget(#gid19,n*20,n*20,30,25,Str(n))
  #gid20=20 : n+1 : ButtonGadget(#gid20,n*20,n*20,30,25,Str(n))
  Repeat
    ev=WaitWindowEvent()
    If ev=#PB_Event_Gadget
      Select EventGadgetID()
        Case #gid1 : Debug "1"
        Case #gid2 : Debug "2"
        Case #gid3 : Debug "3"
        Case #gid4 : Debug "4"
        Case #gid5 : Debug "5"
        Case #gid6 : Debug "6"
        Case #gid7 : Debug "7"
        Case #gid8 : Debug "8"
        Case #gid9 : Debug "9"
        Case #gid10 : Debug "10"
        Case #gid11 : Debug "11"
        Case #gid12 : Debug "12"
        Case #gid13 : Debug "13"
        Case #gid14 : Debug "14"
        Case #gid15 : Debug "15"
        Case #gid16 : Debug "16"
        Case #gid17 : Debug "17"
        Case #gid18 : Debug "18"
        Case #gid19 : Debug "19"
        Case #gid20 : Debug "20"
      EndSelect
    EndIf
  Until ev=#PB_EventCloseWindow
EndIf
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: #PB_ANY for MenuItem

Post by Randy Walker »

Code: Select all

; WITH #PB_ANY

Dim gid(20)
If OpenWindow(1,200,150,600,450,#PB_Window_SystemMenu,"Window")
  CreateGadgetList(WindowID())
  For n=1 To 20
    gid(n)=ButtonGadget(#PB_Any,n*20,n*20,30,25,Str(n))
  Next
  Repeat
    ev=WaitWindowEvent()
    If ev=#PB_Event_Gadget
      For n=1 To 20
        If EventGadgetID()=gid(n) : Debug n : Break : EndIf
      Next
    EndIf
  Until ev=#PB_EventCloseWindow
EndIf
Ok, now I see a disticnt advantage. This type approach was not allowed in GFA Basic (or at least I never figured out how) so I am accustomed to doing it the long way, except I would specify the gadget number as a constant; ButtonGadget(1,20,20,30,25,"button 1")
Then again, my project only uses slightly over hundred gadgets and I only have the one project. Still, I can see where #PB_ANY will be very handy when I port to PureBasic - Thanks PB - also very helpful - excellent sample code comparison too!

Shannara - My project is a database oriented, but each record only has about 50 fields so in my case, the long approach has not been a great challenge. That being my only project, extending the use of #PB_ANY into MenuItem wont help me a lot, but for those with more serious projects, PB's example above does signify a strong advantage so I'm sticking with the motion in favor of this enhancement.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: #PB_ANY for MenuItem

Post by Randy Walker »

- EDITED -
Shannara wrote:...this would be quite helpfull in order to have dynamic menus.
If it is only the gadget constants and #PB_ANY stopping you from having dynamic popups... it shouldn't. Maybe I misunderstood, but i've devised a means of using ONLY one single popup routine to "display" any selection I want. Maybe it can help you. (Should be useful to someone - need to do something to gain myself some brownie points around here. :))

Code: Select all

; Psuedo Dynamic PopUp created by Randy Walker using snippets from PB forum,
; PB manual, MS-refereces and a lot of hacking.
; Enjoy unresticted at your own risk...

; Enumerate each selection possible throughout your entire program here!!!
Enumeration
  #pick_1
  #pick_2
  #pick_3
  #pick_4
  #pick_5
  #pick_6
  #pick_7
  #pick_8
EndEnumeration


; Create dynamic popup "ONLY ONCE" and REUSE as desired!!!
PU_HND.w = CreatePopupMenu(0)   ; Begin creating dynamic pop-up.
If PU_HND
  MenuItem(#pick_1, "ITEM 1") ; just like in a normal menu... 
  MenuItem(#pick_2, "ITEM 2") 
  MenuItem(#pick_3, "ITEM 3") 
  ; "New ITEM 4" Not added yet - See InsertMenu_() below.
  ; "New ITEM 5" Not added yet - See InsertMenu_() below.
EndIf 

Procedure handlePopup(x,y)
  Repeat ; enumerated "Case" options remain static for handling purposes.
    Event = WaitWindowEvent()
    Select Event     ; check for window events.
      Case #WM_RButtonDown       ; right mouse button was clicked.
        PopUpPos = DisplayPopupMenu(0,WindowID(),x,y)  ; now display the popup-menu.
      Case #PB_EventMenu         ; an item of the popup-menu was clicked.
        Select EventMenuID()     ; get the clicked menu item... 
          Case #pick_1 : Debug "Menu: ITEM 1" 
          Case #pick_2 : Debug "Menu: ITEM 2" 
          Case #pick_3 : Debug "Menu: ITEM 3" 
          Case #pick_4 : Debug "Menu: ITEM 4" ;Not added yet.
          Case #pick_5 : Debug "Menu: ITEM 5" ;Not added yet.
          Case #pick_6 : Debug "Menu: ITEM 6" ;Not added yet.
          Case #pick_7 : Debug "Menu: ITEM 7" ;Not added yet.
          Case #pick_8 : Debug "Menu: ITEM 8" ;Not added yet.
            ; This procedure MUST remain static to index properly -AND- all
            ; "Case" selections MUST be included here for every popup item
            ; to be included in your program.
        EndSelect
    EndSelect 
  Until Event = #PB_Event_Menu  ; 
EndProcedure


;/ DO NOT "CreatePopupWindow" AGAIN!!!  Just call handlePopup() as desired.
; Use the "#pick_n" handle to setup your selections before each
; handlePopup() call.  Just insert, delete and modify labels as needed.


;/ Going into 1st popup sample loop...
If OpenWindow(0, 200, 400, 350, 120, #PB_Window_SystemMenu, "Right Click Popup 1 Sample  --  PICK ONE To Continue!") 

  ; 1st setup performed above using CreatePopupWindow()
  handlePopup(210,440)    
  
EndIf 
HideWindow(0,1)  ; hide this window for a moment...


; Now demonstrate "same" dynamic popup on top of "ANOTHER" parent window.

If OpenWindow(1, 200, 500, 350, 120, #PB_Window_SystemMenu, "Right Click Popup 2 Sample  --  PICK ONE To Continue!") 
  
  ; Setup again before calling handlePopup()
  
  ; insert where #pick_2 is, pushing #2 and rest down.
  InsertMenu_(PU_HND,#pick_2, #MFT_STRING ,#pick_4, "New ITEM 4")

  ; insert where #pick_2 is, coming in just below new item 4.
  InsertMenu_(PU_HND,#pick_2, #MFT_STRING ,#pick_5, "New ITEM 5")
  ; 2nd parameter is reference item - indexed relative to #pick_n.
  ; 4th parameter is new item ID as indexed in handlePopup & enumeration.
  ; try swapping these two insertMenu lines for fun.
  ; also try setting both "2nd parameters" to #pick_2.
  handlePopup(240,560) ; uses screen coordinate so figure this yourself :)
  
  
  ; NOW - Popup again for 2nd parent but show ONLY NEW menu items.
  SetWindowTitle(1,"Right Click Popup 3 Sample  --  PICK ONE To Continue!") 
  
  ; Setup again before calling handlePopup()
  
  ; First clear our original items before replacing.
  RemoveMenu_(PU_HND, 0, #MF_BYPOSITION) ;remove first item on list.
  RemoveMenu_(PU_HND, 0, #MF_BYPOSITION) ;do it again.  Item 1 & 5 gone.
  
  ; ... and add 3 new selections, (top and bottom).
  InsertMenu_(PU_HND, 0, #MFT_STRING ,#pick_6, "New ITEM 6") ; 0 for top
  InsertMenu_(PU_HND, 0, #MFT_STRING ,#pick_7, "New ITEM 7") 
  InsertMenu_(PU_HND,-1, #MFT_STRING ,#pick_8, "New ITEM 8")  ; -1 will append
  handlePopup(100,500)
  
  ; NOW - Popup again for 2nd parent but show ONLY NEW menu items.
  SetWindowTitle(1,"Right Click Popup 4 Sample  --  PICK ONE To QUIT!") 
  
  ; Setup again before calling handlePopup()
  
  ModifyMenu_(PU_HND, #pick_6, #MFT_STRING, #pick_6, "2nd New ITEM 6")
  ModifyMenu_(PU_HND, #pick_3, #MFT_STRING, #pick_3, "New ITEM 3")
  handlePopup(100,500)
  
EndIf 
CloseWindow(0)
CloseWindow(1)
End
Last edited by Randy Walker on Fri Oct 15, 2004 6:19 pm, edited 1 time in total.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Karbon
PureBasic Expert
PureBasic Expert
Posts: 2010
Joined: Mon Jun 02, 2003 1:42 am
Location: Ashland, KY
Contact:

Post by Karbon »

#PB_Any still feels like a hack to me. I do see the benefit if you are dynamically creating gadgets, but to use this feature all the time just isn't necessary - especially when the bulk of GUI design is done through a WYSIWYG editor like Visual Designer or PureVision. If Paul had changed PureVision to use PB_Any it would have invalidated all code written with PureVision. I don't want to go through all my code and change the constants to variables and I think Paul feels the same way.

I have an extremely large PB project with a whole lot of controls - I've never had a crash due to a high enumeration value. If you can reproduce that, report it as a bug!
-Mitchell
Check out kBilling for all your billing software needs!
http://www.k-billing.com
Code Signing / Authenticode Certificates (Get rid of those Unknown Publisher warnings!)
http://codesigning.ksoftware.net
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

Horses for courses.

PureBasic is richer for having #PB_Any. It is not the best approach all of the time, but it is the better approach some of the time.

:)
@}--`--,-- A rose by any other name ..
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> #PB_Any still feels like a hack to me

There were many people requesting it over and over in the past (do a search
and you'll see) which is why it was eventually added. This is not meant to set
a precedent though!
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Post by Randy Walker »

I agree with both sides... #PB_ANY feels like a hack, and enumeration is a bother. I could say the same about programming too :lol:
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Randy Walker
Addict
Addict
Posts: 991
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Post by Randy Walker »

I cleanup up my code a bit to make the demo more user friendly.

Also added ModifyMenu to just rename an item.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Karbon
PureBasic Expert
PureBasic Expert
Posts: 2010
Joined: Mon Jun 02, 2003 1:42 am
Location: Ashland, KY
Contact:

Post by Karbon »

I know people wanted it.. I'm glad that it was just added on and not changed.
-Mitchell
Check out kBilling for all your billing software needs!
http://www.k-billing.com
Code Signing / Authenticode Certificates (Get rid of those Unknown Publisher warnings!)
http://codesigning.ksoftware.net
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post by tinman »

Karbon wrote:#PB_Any still feels like a hack to me. I do see the benefit if you are dynamically creating gadgets...
Not just that, but if you are writing some functions which create windows and gadgets for general use then #PB_Any means you aer guaranteed not to interfere with any other gadgets in the users code. Remember that any gadget ID must be completely unique across the entire application (something else I'm not a fan of), so hardcoding everything isn't great.

Of course, doing it that way also became less hassle since the introduction of enumerations, so the advantage of #PB_Any isn't as big as it was.

I tend to use both styles depending on the size of the project and what it needs to do. I'm glad we have that ability.
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
Post Reply