GUI Button won't activate second time

Get help with using AutoHotkey and its commands and hotkeys
Yamiko_Hikari
Posts: 9
Joined: 03 Nov 2020, 14:19

GUI Button won't activate second time

Post by Yamiko_Hikari » 24 Jan 2021, 16:48

Hi!

I am trying to make a script for working out (not really, just for practicing coding, but the idea for it came from exercises :lol: )

Description of what this script does:
You press the START button. A round starts and a green progress bar shows the progress. If you don't press the REST button, the script will keep restarting the round. If you press the REST button, the script pauses the progress of the round, starts a rest timer with a red progress bar and after the rest time is up, continues running the round again.
The problem is that the rest button, despite being activated, won't work at all if you press it a second time in one round. It works the first time, but then, it doesn't react to clicking at all, I even added a tooltip to track whether the "Rest" label gets activate. However, when a new round starts, pressing the rest button works again. So basically it works only once per round.

Here is the code:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.


RoundDuration:=10
RestDuration:=5
RestTime:=0
PauseUsed:=false


Gui, New														
Gui, Add, Progress, Hidden xp y10 h30 w1800 cRed BackgroundBlue vRestBar Range0-%RestDuration%, 0
Gui, Font, s90, Arial
Gui, Add, Button, vStartb gStart x50 y150 w600 h300, Start
Gui, Add, Progress, Hidden xp y+10 h30 w1800 cGreen BackgroundBlue vProgressBar Range0-%RoundDuration%, 0
Gui, Add, Button, Disabled vRestbutton gRest x50 y500 w600 h300, Rest

Gui, Show, Maximize Center 
return

Start:
GUIControl, Hide, startb
GUIControl, Show, stopb
gosub RoundStart
return

RoundStart:
RestUsed:=false
SavedRoundTime:=0
GUIControl, Enable, restbutton
Roundtime:=0
gosub RoundTimer
gosub RoundStart
return

RoundTimer:
t1:=A_TickCount
GUIControl, Show, ProgressBar
While (RoundTime<RoundDuration+1) {
	if (RestUsed) {
		Roundtime:=SavedRoundTime+(A_TickCount-t1-RestTime)/1000
		RoundTime:=Floor(RoundTime)
	} else {
		RoundTime:=(A_TickCount-t1-RestTime)/1000
		RoundTime:=Floor(RoundTime)
	}
	GUIControl, ,ProgressBar, %RoundTime%
}
return

Rest:
tooltip, You pressed the Rest button
GUIControl, Disable, restbutton
RestUsed:=true
SavedRoundTime:=RoundTime
gosub RestTimer
GUIControl, Enable, restbutton
RestTime:=0
gosub RoundTimer
return

RestTimer:
t2:=A_TickCount
GUIControl, Show, RestBar
while (RestTime<RestDuration+1) {
	RestTime:=(A_TickCount-t2)/1000
	RestTime:=Floor(RestTime)
	GUIControl, ,RestBar, %RestTime%
}
GUIControl, Hide, RestBar
Return

Esc::
ExitApp


I suppose one of my problems is not being able to optimize well, or use the right methods. I tried switching from sub-routines to functions (not sure if that changes much). It worked the same.

Please help me understand how to fix this. I would be really thankful :)
User avatar
mikeyww
Posts: 5304
Joined: 09 Sep 2014, 18:38

Re: GUI Button won't activate second time

Post by mikeyww » 24 Jan 2021, 17:16

It appears that your While loop is still executing when you press the button the second time. This means that the Rest routine has actually not completed, because the Gosub within it has not returned.

In some cases, a timer can be a better option. There might also be other ways to rearrange the flow so that you are not preventing the Rest routine from finishing.
User avatar
Spawnova
Posts: 456
Joined: 08 Jul 2015, 00:12
Contact:

Re: GUI Button won't activate second time

Post by Spawnova » 24 Jan 2021, 17:47

mikeyww is correct, when you pressed the rest button you then went into a rest loop which worked, followed by going into your work loop which then had to be finished before you could press the button again.

Here's another way to write your script but with a timer this time, which will not lock up your buttons.

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.


work := {duration:10,current:0}
rest := {duration:5,current:0,active:0}

Gui, Add, Progress, Hidden xp y10 h30 w1800 cRed BackgroundBlue vRestBar Range0-100, 0
Gui, Font, s90, Arial
Gui, Add, Button, vStartb gStart x50 y150 w600 h300, Start
Gui, Add, Progress, Hidden xp y+10 h30 w1800 cGreen BackgroundBlue vProgressBar Range0-100, 0
Gui, Add, Button, Disabled vRestbutton gRest x50 y500 w600 h300, Rest
Gui, Show, Maximize Center 
return


main:
if (rest.active) {
	rest.current++
	GUIControl, ,RestBar, % floor((rest.current / rest.duration) * 100)
	if (rest.current = rest.duration) {
		GUIControl, Hide, RestBar
		GUIControl, Enable, restbutton
		rest.active := 0
		rest.current := 0
	}
} else {
	work.current++
	GUIControl, ,ProgressBar, % floor((work.current / work.duration) * 100)
	if (work.current = work.duration)
		work.current := 0
}
return


Start:
GUIControl, Hide, startb
GUIControl, Enable, restbutton
GUIControl, Show, ProgressBar
GUIControl, ,RestBar,0
settimer,main,1000
return


Rest:
settimer,main,1000  ;make sure it waits 1 second before timer starts again
rest.active := 1
GUIControl, Show, RestBar
GUIControl, Disable, restbutton
return

Esc::
guiclose:
ExitApp
Some of my AHK programs: 3D Voxel Game - Platformer Game - Langton's Ant - Raycast light/Pixel Water - Creating HD map of any game
Or check out my Youtube for these plus many more projects! :D
Yamiko_Hikari
Posts: 9
Joined: 03 Nov 2020, 14:19

Re: GUI Button won't activate second time

Post by Yamiko_Hikari » 24 Jan 2021, 19:37

mikeyww wrote: It appears that your While loop is still executing when you press the button the second time. This means that the Rest routine has actually not completed, because the Gosub within it has not returned.

In some cases, a timer can be a better option. There might also be other ways to rearrange the flow so that you are not preventing the Rest routine from finishing.
Spawnova wrote: mikeyww is correct, when you pressed the rest button you then went into a rest loop which worked, followed by going into your work loop which then had to be finished before you could press the button again.

Here's another way to write your script but with a timer this time, which will not lock up your buttons.

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.


work := {duration:10,current:0}
rest := {duration:5,current:0,active:0}

Gui, Add, Progress, Hidden xp y10 h30 w1800 cRed BackgroundBlue vRestBar Range0-100, 0
Gui, Font, s90, Arial
Gui, Add, Button, vStartb gStart x50 y150 w600 h300, Start
Gui, Add, Progress, Hidden xp y+10 h30 w1800 cGreen BackgroundBlue vProgressBar Range0-100, 0
Gui, Add, Button, Disabled vRestbutton gRest x50 y500 w600 h300, Rest
Gui, Show, Maximize Center 
return


main:
if (rest.active) {
	rest.current++
	GUIControl, ,RestBar, % floor((rest.current / rest.duration) * 100)
	if (rest.current = rest.duration) {
		GUIControl, Hide, RestBar
		GUIControl, Enable, restbutton
		rest.active := 0
		rest.current := 0
	}
} else {
	work.current++
	GUIControl, ,ProgressBar, % floor((work.current / work.duration) * 100)
	if (work.current = work.duration)
		work.current := 0
}
return


Start:
GUIControl, Hide, startb
GUIControl, Enable, restbutton
GUIControl, Show, ProgressBar
GUIControl, ,RestBar,0
settimer,main,1000
return


Rest:
settimer,main,1000  ;make sure it waits 1 second before timer starts again
rest.active := 1
GUIControl, Show, RestBar
GUIControl, Disable, restbutton
return

Esc::
guiclose:
ExitApp
Thank you, mikeyww and Spawnova! This is really making the cogs in my head turn and I am starting to understand how this works :D
Post Reply

Return to “Ask For Help”