My timer script Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Pepineros
Posts: 45
Joined: 16 Apr 2018, 17:26
Location: Ireland

My timer script

18 Nov 2018, 11:35

Hello AHKommunity!

I would like to share with you the code of my focus/break timer script. It counts up from 0 whenever the user hits "Start", displaying both the time that has passed and either "FOCUS" or "BREAK" depending on which part of the cycle you're in. Each time the user hits "Stop" after a focus or break period, the script writes the start date&time, end date&time, duration, and state to a csv file.

Two questions
1. In order to have the GUI sit flush to the right hand side of the screen I'm calculating A_Screenwidth minus width of the GUI and using that as the x value of the GUI position, like below (note these lines are not next to each other in the script, I'm just putting them like this to clarify what I'm doing)

Code: Select all

flush := A_Screenwidth-120
gui,show,w120 x%flush% y500
However when I do this, the GUI actually extends 36px beyond the width of the screen. It sits exactly flush if I use A_Screenwidth-156 instead. Why is the GUI (apparently) 156px wide if I specify it to be 120px in the gui,show command?
A_Screenwidth returns 1920 as expected for my display.

2. Currently in order to display the correct time in the GUI's Edit2 control I use 2 variables (%secs% for seconds and %mins% for minutes), plus 25 lines of code with nested ifs. I feel like this could be done much more efficiently. I don't mind only using a single %time% var which the GUI calculates into minutes+seconds itself instead of using 2 separate vars. I do need the time to always show zeroes as opposed to emptiness in the GUI, so secs<10 and mins<10 would have a leading 0, if mins=0 it should display two zeroes, etc.
Could anyone suggest what logic I should try to follow, sources I could learn from, or provide some sample code for me to adapt?

x. Any other feedback or general comments about my code are much appreciated! As you can probably tell I'm only just starting to learn how to use AHK for more than just remapping some keys.

Full code

Code: Select all

/*
REVERSE POMODORO TIMER
v1.0 Nov 18 2018
Credit to Mannaia- for the foundation of this script at https://autohotkey.com/board/topic/67777-display-the-results-of-any-variable-a-gui-window/
Credit to flyingDman for his timer script at https://autohotkey.com/board/topic/113024-simple-countdown-timer/
*/

#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.
#notrayicon
#singleinstance,force

flush := A_Screenwidth-150
mins := 0
secs := 0
state := "FOCUS"

gui,-border
gui,add,button,x6 y78 w51 h20 gRun default,Start 		; this will call the function Run.
gui,add,button,x63 y78 w51 h20 disabled gToggle,Stop	; add a disabled button to stop the counter
gui,font,cgreen s12 bold,verdana
gui,add,edit,x18 y6 w90 h20 -E0x200 readonly,%state%
gui,font,cGreen s19 bold,verdana
gui,add,edit,x6 y32 w108 h36 readonly center
gui,show,w120 x%flush% y500, Pomodoro
guicontrol,,edit2,00:00									; without this the timer is empty instead of 0s
winset,alwaysontop,on,a
return

Run:
guicontrol,-disabled,Button2 							; activate stop button
formattime,timeatstart,,yyyyMMdd,HH:mm 					; get timestamp when starting count
settimer,count,1000
return

count:
	++secs												; increment seconds var by 1
	if(secs=60)											; if after incrementing the secs var is 60...
		{
		++mins											; increment mins var by 1, and
		secs := 0										; reset secs to 0
		if(mins<10)
			guicontrol,,edit2,0%mins%:00				; manually add a leading 0 if mins<10
		else
			guicontrol,,edit2,%mins%:00
		}
	else if(secs<10)
		{
		if(mins<10)
			guicontrol,,edit2,0%mins%:0%secs%			; manually add leading 0 if both<10, or
		else
			guicontrol,,edit2,%mins%:0%secs%			; only to secs if secs<10
		}
	else
		{
		if(mins<10)
			guicontrol,,edit2,0%mins%:%secs%
		else
			guicontrol,,edit2,%mins%:%secs%
		}
	gui,submit,nohide	 								; save and show the changes
Return

Toggle:
settimer,count,off	 									; stop the count loop
formattime,timeatstop,,yyyyMMdd,HH:mm 					; get timestamp when ending count
gosub,log
mins := 0
secs := 0
if(state = "FOCUS")
	state := "BREAK"
else
	state := "FOCUS"
guicontrol,+disabled,Button2 							; disable the Stop button
guicontrol,,edit1,%state%								; set correct state label
guicontrol,,edit2,00:00									; manually add zeroes to timer
gui submit,nohide 										; save changes and return to the main gui
Return

log:
	FileAppend,
		(
		`n%timeatstart%,%timeatstop%,%mins%,%secs%,%state%
		),pmdr/tracker.csv
return

#esc::exitapp
Much obliged!

- P
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: My timer script

18 Nov 2018, 12:13

Wn: Specify for n the width (in pixels) of the window's client area (the client area excludes the window's borders, title bar, and menu bar).
use WinGetPos, calculations and WinMove to reposition it correctly afterwards
Pepineros
Posts: 45
Joined: 16 Apr 2018, 17:26
Location: Ireland

Re: My timer script

18 Nov 2018, 13:09

swagfag wrote:
18 Nov 2018, 12:13
Wn: Specify for n the width (in pixels) of the window's client area (the client area excludes the window's borders, title bar, and menu bar).
use WinGetPos, calculations and WinMove to reposition it correctly afterwards
Thanks for your reply! I specify the width of the client area as 120 but when checking with Windowspy the client's width is 150. The total width of the GUI window is 156, so the border and such add a little bit but not a full 36px. I specify gui,-border in my code to get rid of the title bar and borders.

All info from Windowspy's Active Window Position section:
x: 1764 y: 500 w: 156 h: 137
Client: x: 0 y: 0 w: 150 h: 131

Still unclear as to why setting the width in gui,show gets overruled by something.

- P
Pepineros
Posts: 45
Joined: 16 Apr 2018, 17:26
Location: Ireland

Re: My timer script

18 Nov 2018, 23:46

Update on question 1
Yesterday after restarting the window was showing a client width of 120 and window width of 126 in Windowspy. After I finished working I shut down, booted up again just now, and guess what... back to 150/156.
I can work around it by letting the script grab the window size instead of assuming it simply does what I tell it to do but I'm still confused by this behaviour. Any root causes are still welcome :)
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: My timer script  Topic is solved

19 Nov 2018, 03:18

Could anyone suggest what logic I should try to follow, sources I could learn from, or provide some sample code for me to adapt?

Try replacing your count: routine with a single line:

Code: Select all

count:
    guicontrol,,edit2, % Format("{:02}:{:02}", ++secs//60, Mod(secs, 60))
Return
I hope that helps.
Pepineros
Posts: 45
Joined: 16 Apr 2018, 17:26
Location: Ireland

Re: My timer script

19 Nov 2018, 15:28

Thanks wolf, that does exactly what I need!

I shall go forth and learn about Format() :+1:
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: My timer script

19 Nov 2018, 15:54

Perhaps you'll like FORMAT FUNCTION EXAMPLES. Cheers.
jeeswg's characters tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=26486
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: My timer script

19 Nov 2018, 15:55

I think my line may have broken the logging, fix: also untested.

Code: Select all

count:
    guicontrol,,edit2, % Format("{:02}:{:02}", mins := (++secs//60), secs := Mod(secs, 60))
Return

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: aitaixy, Nerafius, RandomBoy and 197 guests