Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Trying to create a simple menu
#1
I'm trying to change the active state of my main loop with a simple menu.  Everything seems to work, but when I press 'Enter' on the 'Get Out' menu item, nothing happens.  QB64PE does pass parameters by reference doesn't it?  I'm not really sure why my main loop won't exit.

Code: (Select All)

''Create a menu with selectable options
Option _Explicit
$Color:0

''main program area
Dim state&: state& = 1

Do
    _Limit (60)
    PopUpMenu (state&)
Loop Until state& = 0

Sleep
End


''----------------------Subroutines--------------------------
Sub PopUpMenu (pustate&)

    ''routine for popup menu - active subsystems should check for their own input
    Dim mrtxt$(1 To 4)
    mrtxt$(1) = "Hello"
    mrtxt$(2) = "Goodbye"
    mrtxt$(3) = "Now"
    mrtxt$(4) = "Get Out"

    Static msel&

    ''Check for input
    If _KeyDown(18432) Then ''up
        msel& = msel& - 1
    End If

    If _KeyDown(20480) Then ''down
        msel& = msel& + 1
    End If
    ''wrap menu cursor
    If msel& < LBound(mrtxt$) Then msel& = UBound(mrtxt$)
    If msel& > UBound(mrtxt$) Then msel& = LBound(mrtxt$)

    If _KeyDown(13) Then ''Enter
        ''Exit the program when enter is pressed on Get Out
        If msel& = 4 Then pustate& = 0
    End If

    ''Draw the menu to the screen
    DrawMenuBox 3, 4, mrtxt$(), msel&

    Sleep .001

End Sub ''PopUpMenu


Sub DrawMenuBox (row&, col&, mtxt$(), hl&)

    ''Draw a menu Box on the screen
    Dim tw&, th&

    ''Get the number of lines of text to draw and determine the longest
    th& = UBound(mtxt$) - LBound(mtxt$) + 1

    Dim i
    For i = LBound(mtxt$) To UBound(mtxt$)
        If Len(mtxt$(i)) > tw& Then tw& = Len(mtxt$(i))
    Next

    ''Generate the text Box
    Color Black, White
    ''top row
    Locate row&, col&
    Print "�" + String$(tw&, "�") + "�"

    ''Print txt rows
    For i = 1 To th&
        Locate row& + i, col&
        Print "�" + Space$(tw&) + "�"
    Next

    ''bottom row
    Locate row& + th& + 1, col&
    Print "�" + String$(tw&, "�") + "�"

    ''Print text onto box
    For i = 1 To th&
        If i = hl& Then
            Color White, Black
            Locate row& + i, col& + 1
            Print mtxt$(i) + Space$(tw& - Len(mtxt$(i)))
            Color Black, White
        Else
            Locate row& + i, col& + 1
            Print mtxt$(i) + Space$(tw& - Len(mtxt$(i)))
        End If
    Next

End Sub

I hope this isn't something dumb again.  Big Grin
Reply
#2
I see it isn't sending the zero value back to the calling sub.

Ah, you need to remove the parenthesis around the passing variable...

Change: PopUpMenu (state&) to PopUpMenu state&
Reply
#3
Here is simplest thing to show an action when getout enter, I also removed the parameter to menu sub and just shared state with main and all routines. You might now use state in select case to run the routine on each menu item:
Code: (Select All)
''Create a menu with selectable options
Option _Explicit
$Color:0

''main program area
Dim Shared state&: state& = 1

Do
    _Limit (60)
    PopUpMenu
Loop Until state& = 0

Sleep
End


''----------------------Subroutines--------------------------
Sub PopUpMenu

    ''routine for popup menu - active subsystems should check for their own input
    Dim mrtxt$(1 To 4)
    mrtxt$(1) = "Hello"
    mrtxt$(2) = "Goodbye"
    mrtxt$(3) = "Now"
    mrtxt$(4) = "Get Out"

    Static msel&

    ''Check for input
    If _KeyDown(18432) Then ''up
        msel& = msel& - 1
    End If

    If _KeyDown(20480) Then ''down
        msel& = msel& + 1
    End If
    ''wrap menu cursor
    If msel& < LBound(mrtxt$) Then msel& = UBound(mrtxt$)
    If msel& > UBound(mrtxt$) Then msel& = LBound(mrtxt$)

    If _KeyDown(13) Then ''Enter
        ''Exit the program when enter is pressed on Get Out
        If msel& = 4 Then state& = 0: End
    End If

    ''Draw the menu to the screen
    DrawMenuBox 3, 4, mrtxt$(), msel&

    Sleep .001

End Sub ''PopUpMenu


Sub DrawMenuBox (row&, col&, mtxt$(), hl&)

    ''Draw a menu Box on the screen
    Dim tw&, th&

    ''Get the number of lines of text to draw and determine the longest
    th& = UBound(mtxt$) - LBound(mtxt$) + 1

    Dim i
    For i = LBound(mtxt$) To UBound(mtxt$)
        If Len(mtxt$(i)) > tw& Then tw& = Len(mtxt$(i))
    Next

    ''Generate the text Box
    Color Black, White
    ''top row
    Locate row&, col&
    Print "?" + String$(tw&, "?") + "?"

    ''Print txt rows
    For i = 1 To th&
        Locate row& + i, col&
        Print "?" + Space$(tw&) + "?"
    Next

    ''bottom row
    Locate row& + th& + 1, col&
    Print "?" + String$(tw&, "?") + "?"

    ''Print text onto box
    For i = 1 To th&
        If i = hl& Then
            Color White, Black
            Locate row& + i, col& + 1
            Print mtxt$(i) + Space$(tw& - Len(mtxt$(i)))
            Color Black, White
        Else
            Locate row& + i, col& + 1
            Print mtxt$(i) + Space$(tw& - Len(mtxt$(i)))
        End If
    Next

End Sub

Also 
Code: (Select All)
    Dim mrtxt$(1 To 4)
    mrtxt$(1) = "Hello"
    mrtxt$(2) = "Goodbye"
    mrtxt$(3) = "Now"
    mrtxt$(4) = "Get Out"
 Can be moved to main and done once and for all time with DIm Shared mrtxt$()
b = b + ...
Reply
#4
(05-12-2025, 08:48 PM)Pete Wrote: I see it isn't sending the zero value back to the calling sub.

Pete's drinking.  What he's saying has nothing to do with your problem.  Ignore him 100%.  Big Grin

    PopUpMenu (state&)    <--- This line is the problem, and I think it's one you've had before.

*DON'T use parenthesis with SUB calls.  It prevents passing of values back and forth.

Change that to the following and it works:

    PopUpMenu state&

OR Change it to the following and it works:

    CALL PopUpMenu (state&)

But as you have it, you're not passing values back and forth and as such you're not getting that exit value back from the SUB.  That's the only problem I see with what you've got here.  You simply can't pass values back and forth inside parenthesis like that.
Reply
#5
I posted that () removal Tongue ... and yes, I'm also drinking. Big Grin 

I used to do sub calls with CALL mysub.. which needs () so I didn't notice it at first. Had to edit the post when I noticed the variable wasn't being returned, even though it was properly zeroed in the subroutine.

Pete
Reply
#6
(05-12-2025, 08:48 PM)Pete Wrote: I see it isn't sending the zero value back to the calling sub.

Ah, you need to remove the parenthesis around the passing variable...

Change:    PopUpMenu (state&)  to    PopUpMenu state&

I literally made this exact same mistake about three posts ago.  I knew it was going to be something dumb.  Thanks everyone. Maybe in the next release the compiler can be made to throw a syntax error when parenthesis are used with a sub without CALL. Then again, I'm probably the only person who has this problem.
Reply
#7
One more dumb question.  I'll post it here to keep from cluttering the forum.  Does the qb64pe compiler preserve the c/c++ files it has already built for speeding up compile times?  Is there any way to force a clean build?  I'm asking this because when I made changes to my code above, I was still having to hit Enter twice to exit the program.  It didn't make sense till I deleted some variables, recompiled, then restored those variables and recompiled again.  Please note, the code is the same as it was before, but after changing some things then changing them back things started working like they were supposed to.

Also, I'm not talking about the 'End' message you get after the program completes.  I was pressing 'Enter' on the 'Get Out' option on my menu, but then I would have to press another key to before it would exit the do loop.
Reply
#8
Is what I'm trying to do here just too janky or something?  This is the latest iteration, and logically, it should display a screen of randomly generated lines, then let you open a menu over those lines while they continue to draw.  Instead when you open the menu, the lines stop drawing, and the menu can't be seen.  Maybe I've done something dumb.  I don't know.

Code: (Select All)

''Draw lines and create a menu over it using drawing planes
Option _Explicit
$Color:0

Screen _NewImage(640, 480, 32)
Randomize Timer

''Drawing planes - will be drawn in order to the screen
Dim plane&(1 To 3)
plane&(1) = _NewImage(640, 480, 32) ''lines
plane&(2) = _NewImage(640, 480, 32) ''menu
plane&(3) = _NewImage(640, 480, 32) ''whatever

''main program area
Dim lstate&: lstate& = 1
Dim mstate&: mstate& = 0

Do
    _Limit (60)
    ''test for keypresses
    If _KeyHit > 0 Then
        mstate& = 1
    End If

    ''Draw lines
    RndLines plane&(1)

    ''menu
    If mstate& Then
        PopUpMenu lstate&, mstate&, plane&(2)
    End If

    ''draw all planes to the screen - should work if transparent is 0
    _PutImage , plane&(1), 0
    _PutImage , plane&(2), 0
    _PutImage , plane&(3), 0

    _Display
Loop Until lstate& = 0

_FreeImage plane&(1)
_FreeImage plane&(2)
_FreeImage plane&(3)

System


''----------------------Subroutines--------------------------
Sub PopUpMenu (loopst&, menust&, sbuff&)

    ''routine for popup menu - active subsystems should check for their own input
    Dim mrtxt$(1 To 4)
    mrtxt$(1) = "Resume"
    mrtxt$(2) = "Restart"
    mrtxt$(3) = "Quit"
    mrtxt$(4) = "Get Out"

    Static msel&

    ''Check for input
    If _KeyDown(18432) Then ''up
        msel& = msel& - 1
    End If

    If _KeyDown(20480) Then ''down
        msel& = msel& + 1
    End If
    ''wrap menu cursor
    If msel& < LBound(mrtxt$) Then msel& = UBound(mrtxt$)
    If msel& > UBound(mrtxt$) Then msel& = LBound(mrtxt$)

    If _KeyDown(13) Then ''Enter
        ''Exit the program when enter is pressed on Get Out
        Select Case msel&
            Case 1
                ''close the menu
                menust& = 0: Exit Sub
            Case 2
                ''Restart the drawing
                menust& = 0
                Cls: Exit Sub
            Case 3, 4
                ''quit the program
                loopst& = 0: System
        End Select
    End If

    ''Draw the menu to the screen
    DrawMenuBox 3, 4, mrtxt$(), msel&, sbuff&

    Sleep .001

End Sub ''PopUpMenu


Sub DrawMenuBox (row&, col&, mtxt$(), hl&, sbuff&)

    ''Draw a menu Box on the screen
    Dim tw&, th&, scr&

    ''change the drawing destination
    scr& = _Dest
    _Dest sbuff&

    ''Get the number of lines of text to draw and determine the longest
    th& = UBound(mtxt$) - LBound(mtxt$) + 1

    Dim i
    For i = LBound(mtxt$) To UBound(mtxt$)
        If Len(mtxt$(i)) > tw& Then tw& = Len(mtxt$(i))
    Next

    ''Generate the text Box
    Color Black, White
    ''top row
    Locate row&, col&
    Print "�" + String$(tw&, "�") + "�"

    ''Print txt rows
    For i = 1 To th&
        Locate row& + i, col&
        Print "�" + Space$(tw&) + "�"
    Next

    ''bottom row
    Locate row& + th& + 1, col&
    Print "�" + String$(tw&, "�") + "�"

    ''Print text onto box
    For i = 1 To th&
        If i = hl& Then
            Color White, Black
            Locate row& + i, col& + 1
            Print mtxt$(i) + Space$(tw& - Len(mtxt$(i)))
            Color Black, White
        Else
            Locate row& + i, col& + 1
            Print mtxt$(i) + Space$(tw& - Len(mtxt$(i)))
        End If
    Next

    ''restore color and drawing destination
    Color White, Black
    _Dest scr&

End Sub ''DrawMenuBox


Sub RndLines (sbuff&)

    ''Draw random lines across the screen
    Dim x1&, y1&, x2&, y2&, scr&
    Dim linecolor As _Unsigned Long

    ''Randomize the color
    linecolor = _RGB(Int(Rnd * 255), Int(Rnd * 255), Int(Rnd * 255))

    ''Randomize the line points
    x1& = Int(Rnd * _Width)
    y1& = Int(Rnd * _Height)
    x2& = Int(Rnd * _Width)
    y2& = Int(Rnd * _Height)

    ''Draw the line
    scr& = _Dest
    _Dest sbuff&
    Line (x1&, y1&)-(x2&, y2&), linecolor
    _Dest scr&

End Sub


Here is the executable file in case people can't reproduce my issues.  I'm using Linux Mint 22.1 AMD64.
https://mega.nz/folder/f2RChbrC#hQF0KBiEjmALijWNNWhDGA
Reply




Users browsing this thread: 1 Guest(s)