none
Small Basic Event help RRS feed

  • Question

  • Hello,

    I am having slight trouble understanding the specs of the event functions for the controls.buttonclicked event.  Previously, I thought by putting the name of a subroutine at the end of it (i.e. Controls.ButtonClicked = subroutine) that it would process that particular subroutine, but I have run into troubles as I try to call upon subroutines located above the given code that is being processed (it won't go to a subroutine that is above the code it is reading.) Is there a particular reason for this that I am not understanding?  And if so, how to I make any button click on a certain screen activate a certain subroutine located earlier in the program (I want to redo a certain section of the program over again after any button on a screen is pressed.)

    Thank you

    Friday, June 8, 2012 1:31 AM

Answers

  • Hi there, Otis!

    I see you're coding some kid school management program? Seems very nice!

    But alas; I knew it wouldn't be that easy to make you grasp what I was trying to convey from my replies above, by only leaving those 2 code examples for you to figure them out alone.

    I was indeed right thinking you were trying to create new sets of buttons for different screens.
    But to accomplish that, you need to modularize your code even more, especially that Sub Buttons part!

    In fact, for maximum efficiency and organization, that button event Sub should be just like below, nothing else:

    Sub Buttons
    
      operator = Controls.GetButtonCaption(Controls.LastClickedButton)
    
    EndSub

    If your program only needed just 1 "menu" button screen, you wouldn't need all the things I'm about to list!
    However, here's what you have to do for each "menu" screen:

    1. Clear the GraphicsWindow;
    2. Call a subroutine to create buttons for that particular screen;
    3. Make a "wait"-loop, so program stalls until one of the buttons is selected;
    4. Call a "hand-crafted" subroutine tasked to identify only the buttons which are displayed on that particular screen;
    5. If that button was meant to do a task, call a subroutine for that;
    6. If it was to call another "menu" screen, call a subroutine which follows these same strategies here;
    7. And finally, if it was a "go back"-type button, just EndSub it to return to its parent's "menu" screen!

    And now your question about how to make a set of buttons do the same task; in your case, make all of them function as a "go back" button.

    If you coded your program following the scheme above, you'd be able to decide what each button does for a particular screen.
    Since the effect of all of those buttons would be to just to go back to their parent subroutine, it's enough to consider any button pressed to mean go back!
    You don't need to identify which one was clicked if the effect is the same!

    Another option is: if the goal is just to display a class' roster; rather than using buttons to list them, why not use the more simple GraphicsWindow.DrawText()? Along w/ a "go back" button as well.  :P

    So sorry for my harshness!  @_@
    Looking forward to see your edu software working!  ^_^


    Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

    Friday, June 8, 2012 6:37 PM
    Answerer
  • I wrote this up quickly so i'm not sure if there are any errors.

    'Draw Buttons For i = 1 to Array.GetItemCount(lvl6Student) button[i] = Controls.AddButton(level6Student[i],50,1+50*i) EndFor 'Event Controls.ButtonClicked = ButtonChecker 'subrouine for all buttons Sub ButtonChecker LastButtonClicked = Controls.LastClickedButton 'Here is where the buttons get checked For i = 1 To Array.GetItemCount(button) If LastButtonClicked = button[i] 'Have more have 1 if statement if you want mutliple buttons to do different task. 'goto label here EndIf EndFor EndSub

    Saturday, June 9, 2012 12:27 AM
  • Please upload the block of code you think is causing the problem.

    EDITED: The obvious reason for the blinking effect is constantly clearing and redrawing the controls, please make your you are not doing that in your program follow your logic.

    Sunday, June 10, 2012 3:49 AM

All replies

  • Heyya Otis!

    Triggered event questions are an eternal subject!  :P

    But before delving into them, I have to say that setting Controls.ButtonClicked inside subroutines is very buggy, 'cause the triggered event is also a subroutine itself that can be located before or after others; and it confuses the compiler it seems!

    Best procedure is to set Controls.ButtonClicked in the main part of the code, and type all subroutines below it.

    Now, I believe you wanna know how to control buttons when you clear and create more screens? It would help much more if you had published your problematic code for us to analyze it!

    In these 2 previous threads -> Notepad & Dictionary & Making a Simple Calculator.
    you can see good examples on how to deal w/ button events.

    Gonna leave here 2 of my code samples I have there for convenience:

    '================================================'
    ' Notepad & Dictionary '
    '================================================'
    
    InitScreen()
    CreateButtons()
    Controls.ButtonClicked= OnButtonClicked
    
    '================================================'
    ' Sitting-Duck Waiting-Loop: '
    '================================================'
    WaitLoop:
    
    If Button = Exit Then
      Sound.PlayChimeAndWait()
      Program.End()
    EndIf
    
    If Button = Note Then
      Button= ""
      Sound.PlayChimesAndWait()
    EndIf
    
    If Button = Def Then
      Button= ""
      WordDefinition()
    EndIf
    
    Program.Delay(100)
    
    Goto WaitLoop
    '================================================'
    
    '----------------------------------------------------------------------------------'
    Sub OnButtonClicked
      
      Button= Controls.LastClickedButton
      Sound.PlayClick()
      
    EndSub
    '----------------------------------------------------------------------------------'
    Sub InitScreen
      
      GraphicsWindow.Clear()
      GraphicsWindow.Width=  500
      GraphicsWindow.Height= 500
      GraphicsWindow.BackgroundColor= "Green"
      
    EndSub
    '----------------------------------------------------------------------------------'
    Sub CreateButtons
      
      GraphicsWindow.BrushColor= "Red"
      Exit= Controls.AddButton("Exit"       220,40)
      GraphicsWindow.BrushColor= "Blue"
      Note= Controls.AddButton("Notepad"    250,10)
      GraphicsWindow.BrushColor= "Purple"
      Def=  Controls.AddButton("Dictionary" 150,10)
      
    EndSub
    '----------------------------------------------------------------------------------'
    Sub CreateDicButtons
      
      GraphicsWindow.BrushColor= "Green"
      Options= Controls.AddButton("Options"          500, 10)
      GetDef=  Controls.AddButton("Find Definition"  270,100)
      GraphicsWindow.BrushColor= "Red"
      Back=    Controls.AddButton("Back"              10, 10)
      GraphicsWindow.BrushColor= "Blue"
      Defword= Controls.AddTextBox(100,100)
      Definition= Controls.AddMultiLineTextBox(100,200)
      Controls.SetSize(Definition  400,400)
      
    EndSub
    '----------------------------------------------------------------------------------'
    Sub WordDefinition
      
      GraphicsWindow.Clear()
      GraphicsWindow.Width=  1100
      GraphicsWindow.Height= 700
      
      CreateDicButtons()
      
      '=============================================='
      ' Dicitonary Sitting-Duck Waiting-Loop: '
      '=============================================='
      
      While Button <> Back    
        If Button = GetDef Then
          Button= ""
          Typed= Controls.GetTextBoxText (Defword)
          Word=  Dictionary.GetDefinition(Typed)
          Controls.SetTextBoxText(Definition Word)
        EndIf
        Program.Delay(100)    
      EndWhile
      '=============================================='
      
      InitScreen()
      CreateButtons()
      
    EndSub
    '----------------------------------------------------------------------------------'
    ' Calculator (WaitLoop version)'
    '******************************'
    
    '======================================================'
    GW = 350
    GH = 290
    GraphicsWindow.BackgroundColor = "Yellow"
    GraphicsWindow.CanResize = "False"
    GraphicsWindow.Title = "Calculator"
    GraphicsWindow.Width  = GW
    GraphicsWindow.Height = GH
    GraphicsWindow.Left = .5*(Desktop.Width  - GW)
    GraphicsWindow.Top  = .5*(Desktop.Height - GH)
    
    CreateGUI()
    Controls.ButtonClicked = ButtonClicked
    GraphicsWindow.KeyDown = KeyPressed
    '======================================================'
    OperatorWaitLoop:
    
    If Button <> "" Then
      Value1 = Controls.GetTextBoxText(FirstTxtBox )
      Value2 = Controls.GetTextBoxText(SecondTxtBox)
      Operator  = Button
      Button  =  ""
      Calculate()
    EndIf
    Program.Delay(100)
    
    Goto OperatorWaitLoop
    '======================================================'
    
    '---------------------------------------------------------------------------------------------'
    Sub ButtonClicked
      
      Button= Controls.GetButtonCaption(Controls.LastClickedButton)
      Sound.PlayClick()
      
    EndSub
    '---------------------------------------------------------------------------------------------'
    Sub KeyPressed
      
      Key = GraphicsWindow.LastKey
      
      If Key = "Escape" Then
        Sound.PlayChimeAndWait()
        Program.End()
      EndIf
      
    EndSub
    '---------------------------------------------------------------------------------------------'
    Sub CreateGUI
      
      GraphicsWindow.PenColor   = "Black"
      GraphicsWindow.DrawRectangle(10,10  330,270)
      
      GraphicsWindow.FontSize   = 12
      GraphicsWindow.BrushColor = "Green"
      GraphicsWindow.DrawText(50,70   "Enter 1st Number:")
      FirstTxtBox = Controls.AddTextBox(200,60)
      Controls.SetSize(FirstTxtBox   60,30)
      
      GraphicsWindow.DrawText(50,120  "Enter 2nd Number:")
      SecondTxtBox = Controls.AddTextBox(200,110)
      Controls.SetSize(SecondTxtBox  60,30)
      
      GraphicsWindow.BrushColor = "Red"
      GraphicsWindow.DrawText(50,170  "Answer is:")
      AnswerTxtBox = Controls.AddTextBox(200,160)
      Controls.SetSize(AnswerTxtBox 110,30)
      
      GraphicsWindow.FontSize   = 15
      GraphicsWindow.BrushColor = "Blue"
      OperatorBox[1] = Controls.AddButton("+"   20,210)
      OperatorBox[2] = Controls.AddButton("-"   70,210)
      OperatorBox[3] = Controls.AddButton("×"  120,210)
      OperatorBox[4] = Controls.AddButton("÷"  170,210)
      OperatorBox[5] = Controls.AddButton("C"  270,210)
      
      For num = 1 To 5
        Controls.SetSize(OperatorBox[num]  40,40)
      EndFor
      
    EndSub
    '---------------------------------------------------------------------------------------------'
    Sub Calculate
      
      If Operator = "+" Then
        TotalValue = Value1 + Value2
      EndIf
      If Operator = "-" Then
        TotalValue = Value1 - Value2
      EndIf
      If Operator = "×" Then
        TotalValue = Value1 * Value2
      EndIf
      If Operator = "÷" Then
        TotalValue = Value1 / Value2
      EndIf
      
      Controls.SetTextBoxText(AnswerTxtBox  TotalValue)
      
      If Operator = "C" Then
        Controls.SetTextBoxText(FirstTxtBox   "")
        Controls.SetTextBoxText(SecondTxtBox  "")
        Controls.SetTextBoxText(AnswerTxtBox  "")
      EndIf
      
    EndSub
    '---------------------------------------------------------------------------------------------'


    Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

    Friday, June 8, 2012 3:05 AM
    Answerer
  • Okay, that makes much more sense thank you! Now, what if I want any button pressed on a screen to call on a sub routine?  Just some background:  I have an array that prints into buttons on a particular screen, and I want any one of those buttons being pressed to then go back to a subroutine already defined earlier in the code, what way can I go about doing this since I can't possibly make an if-then for every button?

    Friday, June 8, 2012 6:20 AM
  • I don't know exactly what you mean w/o seeing your code.
    But using the incomplete sample 'Notepad & Dictionary' as an example, you can see in the 1st WaitLoop:, when the user clicks on the Def button, it calls the subroutine WordDefinition.
    From there, it clears the screen and creates a new set of buttons, 1 of them is the Back button.
    It keeps bound to the 2nd waiting-loop until the Back button is pressed. Once it happens, it returns to the 1st WaitLoop: at the beginning!
    Dunno if that's what you're needing though. ?_?

    Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

    Friday, June 8, 2012 6:53 AM
    Answerer
  • Still trying to understand what you want.
    I don't think you can predefine what each button auto-executes when they're pressed.
    SB is not object-oriented and can't have code embedded inside buttons, or any other object for that matter!

    What you can do is:

    1. Program awaits until some button is selected by the user.
    2. Then identifies which one was.
    3. And finally, do something based on it.
    4. Go back to wait for more button clicks!


    Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

    Friday, June 8, 2012 7:07 AM
    Answerer
  • Otis,

    You will  need to write an IF statement for each possible out come from the button press as each button will have its own specific use. If two buttons do the same thing then a sub routine would be the obvious answer.

    I would create a routine which handles all the button presses and checks what button was pressed then pass the task onto a sub routine specific for that button. Therefore it would be easier to manage multiple buttons.

    Friday, June 8, 2012 10:54 AM
  • Okay, first of all thank you for all of your help; I'm starting to understand the logic more now, but here's some code so you can look at it and hopefully help me with my new problem now that I understand the logic. So I only inserted a small section of the code to try to make it easier to read... the only part of the sub button code I am asking about is the last half, the rest of it works.  On the last part I start printing buttons according to an array (there are four different arrarys printed into buttons enclosed in for statements at the bottom of the code) Now what I hope to do is make it so any button of that array pressed brings the user back to the Sub KidDisplay located at the top of the code, now how do I go about that seeing that the buttons are processed as an array rather than each single button?

    Sub KidDisplay
      KidDisplays:
      GraphicsWindow.Clear()
      Controls.AddButton("Parent-N-Me",100,100)
      Controls.AddButton("Pre-School",300,100)
      Controls.AddButton("Levels 1-3",100,400)
      Controls.AddButton("Levels 4-6",300,400)
      Controls.ButtonClicked = buttons
    EndSub
    Sub buttons
      operator = Controls.GetButtonCaption(Controls.LastClickedButton)
      If operator = "Submit" Then
        Session = Controls.GetTextBoxText(strt + " - " + end)
        EnterRoster()
      ElseIf operator = "Add" Then
        If Controls.LastClickedButton = PnMb Then
          GraphicsWindow.DrawText(500,100,Controls.GetTextBoxText(PnM))
          PnMStudent[s] = Controls.GetTextBoxText(PnM)
          s = s + 1 
        Elseif Controls.LastClickedButton = Preb then
          GraphicsWindow.DrawText(500,200,Controls.GetTextBoxText(Pre))
          PreStudent[t] = Controls.GetTextBoxText(Pre)
          t = t + 1
        Elseif Controls.LastClickedButton = lvl3b Then
          GraphicsWindow.DrawText(500,300,Controls.GetTextBoxText(lvl3))
          lvl3Student[u] = Controls.GetTextBoxText(lvl3)
          u = u + 1
        Elseif Controls.LastClickedButton = lvl6b Then
          GraphicsWindow.DrawText(500,400,Controls.GetTextBoxText(lvl6))
          lvl6Student[v] = Controls.GetTextBoxText(lvl6)
          v = v + 1
        EndIf
      Elseif operator = "Roster" Then
        TextWindow.Show()
        TextWindow.WriteLine(PnMStudent)
        TextWindow.WriteLine(PreStudent)
        TextWindow.WriteLine(lvl3Student)
        TextWindow.WriteLine(lvl6Student)
      Elseif operator = "Next" Then
        KidDisplay()
      Elseif operator = "Parent-N-Me" then
        GraphicsWindow.Clear()
        For i = 1 to Array.GetItemCount(PnMStudent)
          Controls.AddButton(PnMStudent[i],50,1 + 50*i)
        Endfor
      Elseif operator = "Pre-School" Then
        GraphicsWindow.Clear()
        For i = 1 to Array.GetItemCount(PreStudent)
          Controls.AddButton(PreStudent[i],50,1 + 50*i)
        Endfor
      Elseif operator = "Levels 1-3" Then
        GraphicsWindow.Clear()
        For i = 1 to Array.GetItemCount(lvl3Student)
          Controls.AddButton(lvl3Student[i],50,1 + 50*i)
        Endfor
      Elseif operator = "Levels 4-6" Then
        GraphicsWindow.Clear()
        For i = 1 to Array.GetItemCount(lvl6Student)
          Controls.AddButton(lvl6Student[i],50,1 + 50*i)
        Endfor
    EndIf
    EndSub


    Friday, June 8, 2012 4:20 PM
  • Okay thank you,

    How can I track each button if they are set as an array? I printed the code in the reply above if you wish to look at it...

    Friday, June 8, 2012 4:22 PM
  • You could try using another array.

    For i = 1 to Array.GetItemCount(lvl6Student)
        button[i] = Controls.AddButton(level6Student[i],50,1+50*i)
    EndFor

    Then on the button clicked event you could iterate through the button array and check the button caption.

    Does this help?

    Friday, June 8, 2012 5:10 PM
  • Hi there, Otis!

    I see you're coding some kid school management program? Seems very nice!

    But alas; I knew it wouldn't be that easy to make you grasp what I was trying to convey from my replies above, by only leaving those 2 code examples for you to figure them out alone.

    I was indeed right thinking you were trying to create new sets of buttons for different screens.
    But to accomplish that, you need to modularize your code even more, especially that Sub Buttons part!

    In fact, for maximum efficiency and organization, that button event Sub should be just like below, nothing else:

    Sub Buttons
    
      operator = Controls.GetButtonCaption(Controls.LastClickedButton)
    
    EndSub

    If your program only needed just 1 "menu" button screen, you wouldn't need all the things I'm about to list!
    However, here's what you have to do for each "menu" screen:

    1. Clear the GraphicsWindow;
    2. Call a subroutine to create buttons for that particular screen;
    3. Make a "wait"-loop, so program stalls until one of the buttons is selected;
    4. Call a "hand-crafted" subroutine tasked to identify only the buttons which are displayed on that particular screen;
    5. If that button was meant to do a task, call a subroutine for that;
    6. If it was to call another "menu" screen, call a subroutine which follows these same strategies here;
    7. And finally, if it was a "go back"-type button, just EndSub it to return to its parent's "menu" screen!

    And now your question about how to make a set of buttons do the same task; in your case, make all of them function as a "go back" button.

    If you coded your program following the scheme above, you'd be able to decide what each button does for a particular screen.
    Since the effect of all of those buttons would be to just to go back to their parent subroutine, it's enough to consider any button pressed to mean go back!
    You don't need to identify which one was clicked if the effect is the same!

    Another option is: if the goal is just to display a class' roster; rather than using buttons to list them, why not use the more simple GraphicsWindow.DrawText()? Along w/ a "go back" button as well.  :P

    So sorry for my harshness!  @_@
    Looking forward to see your edu software working!  ^_^


    Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

    Friday, June 8, 2012 6:37 PM
    Answerer
  • Okay, the bits and pieces are there, now I just need to fill in the blanks... I changed it all to the format you gave, and it was working great until I came to a screen with four text boxes and four numbers... All they are doing is blinking very rapidly and I can't imput any text... Why is this happening?  And also, how do call the certain button for any of the array buttons on a screen so if I do have:

    For i = 1 to Array.GetItemCount(lvl6Student)
        button[i] = Controls.AddButton(level6Student[i],50,1+50*i)
    EndFor

    How do I make any button[i] go back to a label earlier?
    Friday, June 8, 2012 9:25 PM
  • I wrote this up quickly so i'm not sure if there are any errors.

    'Draw Buttons For i = 1 to Array.GetItemCount(lvl6Student) button[i] = Controls.AddButton(level6Student[i],50,1+50*i) EndFor 'Event Controls.ButtonClicked = ButtonChecker 'subrouine for all buttons Sub ButtonChecker LastButtonClicked = Controls.LastClickedButton 'Here is where the buttons get checked For i = 1 To Array.GetItemCount(button) If LastButtonClicked = button[i] 'Have more have 1 if statement if you want mutliple buttons to do different task. 'goto label here EndIf EndFor EndSub

    Saturday, June 9, 2012 12:27 AM
  • Okay, that makes perfect sense; I didn't know calling on button[i] would represent any button of the array thank you.  Do you know a fix to the blinking problem I am getting?
    Saturday, June 9, 2012 1:54 AM
  • I believe this might be due to where abouts in your program you are calling a GraphicWindow.Clear(). If you call this function within your main loop and its being called over and over again this can cause blinking/flashing effect as your program in drawing the graphics window then clearing it over and over.

    I can't see anything obvious in the code you have posted that will cause this please check all your source code or post all of your code so I can experience this myself. If you don't wish to put your code on the net email it to me - kirkkaf@hotmail.co.uk 



    • Edited by Kirkkaf Saturday, June 9, 2012 12:56 PM
    Saturday, June 9, 2012 12:55 PM
  • I dont mind posting it on here but before I do I noticed something interesting, when I pasted just the code for that one screen into its own new block, the program ran fine with no blinks and I could enter text in the text boxes and press the buttons just fine, why is it working when it is by itself?
    Saturday, June 9, 2012 10:01 PM
  • Please upload the block of code you think is causing the problem.

    EDITED: The obvious reason for the blinking effect is constantly clearing and redrawing the controls, please make your you are not doing that in your program follow your logic.

    Sunday, June 10, 2012 3:49 AM