Tutorial: How to change Buttons Event Function on fly (ie. OnMouseDown)
Posted: Sun Jul 08, 2018 2:40 pm
What I have found as most clear way to do on my programs, is to change OnMouseDown, OnMouseOut, etc. functions on fly. However, this is not directly supported in Hollywood, so unfortunately your code will get couple of otherwise unnecessary extra lines.
First lets create example program that uses buttons:
If you run this program, you can see three different buttons, if you push them, you will get debugprint to print "button x pressed".
Now suppose I want to change the function into something else, I could try for example something like this (this is otherwise same, but notice couple of extra lines before repeat forever loop:
As you can see from the test of running function "button1func()" before going to repeat forever loop, you can see that the old "button1func()" is indeed replaced with "newfunc()", but when this "button1func()" is executed through OnMouseDown, you can see that it is still actually using the old "button1func()" that was originally put to it when button was being initialised, and by otherwords, the new program works exactly as the old version did, which was not our purpose, since we wanted to change the function associated with the button. This is slightly unfortunate choice in Hollywood, but luckily we can get around it.
First way to get around is that we delete the button and create the same button again with the new function associated with it, instead of the old one. However, this is a risky thing to do since there are so many moving parts that can go wrong, hence here is how i usually do it.
First lets make a one button version of the old version:
Now lets do one change to this program now:
In this new version, instead of Function directly doing what it is planned to be doing, it is calling another function that is doing what it is planning to do.
This would normally be unnecessary, but due to how OnMouseDown and other button events work, if we wish to replace the current function with a new function without creating the button again, this is what we must do.
Now here is the version that is now going to replace this buttons function on fly:
In this version, i added "NewFunc()" again, and then AFTER i made the button 1, i replaced the "realbutton1func" with "newfunc", since function associated with OnMouseDown is "button1func" and "button1func" does nothing else but executes "realbutton1func", it means that if "realbutton1func" is being replaced with another function, then so is OnMouseDowns function in practice.
This Tutorial continues in: https://forums.hollywood-mal.com/viewto ... =11&t=1937
First lets create example program that uses buttons:
Code: Select all
EnableLayers
Function button1func()
DebugPrint("button 1 pressed")
EndFunction
Function button2func()
DebugPrint("button 2 pressed")
EndFunction
Function button3func()
DebugPrint("button 3 pressed")
EndFunction
SetFillStyle(#FILLCOLOR)
Box(50, 100, 100, 100, #RED, {name="button1box"})
Box(200, 100, 100, 100, #GREEN, {name="button2box"})
Box(350, 100, 100, 100, #BLUE, {name="button3box"})
MakeButton(1, #LAYERBUTTON, "button1box", True, False, {OnMouseDown = button1func})
MakeButton(2, #LAYERBUTTON, "button2box", True, False, {OnMouseDown = button2func})
MakeButton(3, #LAYERBUTTON, "button3box", True, False, {OnMouseDown = button3func})
Repeat
WaitEvent()
Forever
Now suppose I want to change the function into something else, I could try for example something like this (this is otherwise same, but notice couple of extra lines before repeat forever loop:
Code: Select all
EnableLayers
Function button1func()
DebugPrint("button 1 pressed")
EndFunction
Function button2func()
DebugPrint("button 2 pressed")
EndFunction
Function button3func()
DebugPrint("button 3 pressed")
EndFunction
SetFillStyle(#FILLCOLOR)
Box(50, 100, 100, 100, #RED, {name="button1box"})
Box(200, 100, 100, 100, #GREEN, {name="button2box"})
Box(350, 100, 100, 100, #BLUE, {name="button3box"})
MakeButton(1, #LAYERBUTTON, "button1box", True, False, {OnMouseDown = button1func})
MakeButton(2, #LAYERBUTTON, "button2box", True, False, {OnMouseDown = button2func})
MakeButton(3, #LAYERBUTTON, "button3box", True, False, {OnMouseDown = button3func})
Function newfunc()
DebugPrint("Red Button Pressed")
EndFunction
button1func = newfunc
button1func()
Repeat
WaitEvent()
Forever
First way to get around is that we delete the button and create the same button again with the new function associated with it, instead of the old one. However, this is a risky thing to do since there are so many moving parts that can go wrong, hence here is how i usually do it.
First lets make a one button version of the old version:
Code: Select all
EnableLayers
Function button1func()
DebugPrint("Button 1 pressed")
EndFunction
SetFillStyle(#FILLCOLOR)
Box(50, 100, 100, 100, #RED, {name="button1box"})
MakeButton(1, #LAYERBUTTON, "button1box", True, False, {OnMouseDown = button1func})
Repeat
WaitEvent()
Forever
Code: Select all
EnableLayers
Function button1func()
realbutton1func()
EndFunction
Function realbutton1func()
DebugPrint("Button 1 pressed")
Function
SetFillStyle(#FILLCOLOR)
Box(50, 100, 100, 100, #RED, {name="button1box"})
MakeButton(1, #LAYERBUTTON, "button1box", True, False, {OnMouseDown = button1func})
Repeat
WaitEvent()
Forever
This would normally be unnecessary, but due to how OnMouseDown and other button events work, if we wish to replace the current function with a new function without creating the button again, this is what we must do.
Now here is the version that is now going to replace this buttons function on fly:
Code: Select all
EnableLayers
Function button1func()
realbutton1func()
EndFunction
Function realbutton1func()
DebugPrint("Button 1 pressed")
EndFunction
Function newfunc()
DebugPrint("Red Button pressed")
EndFunction
SetFillStyle(#FILLCOLOR)
Box(50, 100, 100, 100, #RED, {name="button1box"})
MakeButton(1, #LAYERBUTTON, "button1box", True, False, {OnMouseDown = button1func})
realbutton1func = newfunc
Repeat
WaitEvent()
Forever
This Tutorial continues in: https://forums.hollywood-mal.com/viewto ... =11&t=1937