-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathpomodoor.lua
192 lines (161 loc) · 5.93 KB
/
pomodoor.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
--- Pomodoro module
--------------------------------------------------------------------------------
-- Configuration variables
--------------------------------------------------------------------------------
local pom = {}
pom.bar = {
indicator_height = 0.2, -- ratio from the height of the menubar (0..1)
indicator_alpha = 0.3,
indicator_in_all_spaces = true,
color_time_remaining = hs.drawing.color.green,
color_time_used = hs.drawing.color.red,
c_left = hs.drawing.rectangle(hs.geometry.rect(0, 0, 0, 0)),
c_used = hs.drawing.rectangle(hs.geometry.rect(0, 0, 0, 0))
}
pom.config = {
enable_color_bar = true,
-- Using random productivity blog numbers, because why not
work_period_sec = 52 * 60,
rest_period_sec = 17 * 60
}
pom.var = {
is_active = false,
disable_count = 0,
work_count = 0,
curr_active_type = "work", -- {"work", "rest"}
time_left = pom.config.work_period_sec,
max_time_sec = pom.config.work_period_sec
}
--------------------------------------------------------------------------------
-- Color bar for pomodoor
--------------------------------------------------------------------------------
local function pom_del_indicators()
pom.bar.c_left:delete()
pom.bar.c_used:delete()
end
local function pom_draw_on_menu(target_draw, screen, offset, width, fill_color)
local screeng = screen:fullFrame()
local screen_frame_height = screen:frame().y
local screen_full_frame_height = screeng.y
local height_delta = screen_frame_height - screen_full_frame_height
local height = pom.bar.indicator_height * (height_delta)
target_draw:setSize(hs.geometry.rect(screeng.x + offset, screen_full_frame_height, width, height))
target_draw:setTopLeft(hs.geometry.point(screeng.x + offset, screen_full_frame_height))
target_draw:setFillColor(fill_color)
target_draw:setFill(true)
target_draw:setAlpha(pom.bar.indicator_alpha)
target_draw:setLevel(hs.drawing.windowLevels.overlay)
target_draw:setStroke(false)
if pom.bar.indicator_in_all_spaces then
target_draw:setBehavior(hs.drawing.windowBehaviors.canJoinAllSpaces)
end
target_draw:show()
end
local function pom_draw_indicator(time_left, max_time)
local main_screen = hs.screen.mainScreen()
local screeng = main_screen:fullFrame()
local time_ratio = time_left / max_time
local width = math.ceil(screeng.w * time_ratio)
local left_width = screeng.w - width
pom_draw_on_menu(pom.bar.c_left, main_screen, left_width, width, pom.bar.color_time_remaining)
pom_draw_on_menu(pom.bar.c_used, main_screen, 0, left_width, pom.bar.color_time_used)
end
--------------------------------------------------------------------------------
-- update display
local function pom_update_display()
local time_min = math.floor((pom.var.time_left / 60))
local time_sec = pom.var.time_left - (time_min * 60)
local str = string.format("[%s|%02d:%02d|#%02d]", pom.var.curr_active_type, time_min, time_sec, pom.var.work_count)
pom_menu:setTitle(str)
end
-- stop the clock
-- Stateful:
-- * Disabling once will pause the countdown
-- * Disabling twice will reset the countdown
-- * Disabling trice will shut down and hide the pomodoro timer
function pom_disable()
local pom_was_active = pom.var.is_active
pom.var.is_active = false
if (pom.var.disable_count == 0) then
if (pom_was_active) then
pom_timer:stop()
end
elseif (pom.var.disable_count == 1) then
pom.var.time_left = pom.config.work_period_sec
pom.var.curr_active_type = "work"
pom_update_display()
elseif (pom.var.disable_count >= 2) then
if pom_menu == nil then
pom.var.disable_count = 2
return
end
pom_menu:delete()
pom_menu = nil
pom_timer:stop()
pom_timer = nil
pom_del_indicators()
end
pom.var.disable_count = pom.var.disable_count + 1
end
-- update pomodoro timer
local function pom_update_time()
if pom.var.is_active == false then
return
else
pom.var.time_left = pom.var.time_left - 1
if (pom.var.time_left <= 0) then
pom_disable()
if pom.var.curr_active_type == "work" then
hs.alert.show("Work Complete!", 2)
pom.var.work_count = pom.var.work_count + 1
pom.var.curr_active_type = "rest"
pom.var.time_left = pom.config.rest_period_sec
pom.var.max_time_sec = pom.config.rest_period_sec
else
hs.alert.show("Done resting", 2)
pom.var.curr_active_type = "work"
pom.var.time_left = pom.config.work_period_sec
pom.var.max_time_sec = pom.config.work_period_sec
end
end
-- draw color bar indicator, if enabled.
if (pom.config.enable_color_bar == true) then
pom_draw_indicator(pom.var.time_left, pom.var.max_time_sec)
end
end
end
-- update menu display
local function pom_update_menu()
pom_update_time()
pom_update_display()
end
local function pom_create_menu(pom_origin)
if pom_menu == nil then
pom_menu = hs.menubar.new()
pom.bar.c_left = hs.drawing.rectangle(hs.geometry.rect(0, 0, 0, 0))
pom.bar.c_used = hs.drawing.rectangle(hs.geometry.rect(0, 0, 0, 0))
end
end
-- start the pomodoro timer
function pom_enable()
pom.var.disable_count = 0;
if (pom.var.is_active) then
return
end
pom_create_menu()
pom_timer = hs.timer.new(1, pom_update_menu)
pom.var.is_active = true
pom_timer:start()
end
-- reset work count
-- TODO - reset automatically every day
function pom_reset_work()
pom.var.work_count = 0;
end
-- Use examples:
-- init pomodoro -- show menu immediately
-- pom_create_menu()
-- pom_update_menu()
-- show menu only on first pom_enable
-- hs.hotkey.bind(mash, '9', function() pom_enable() end)
-- hs.hotkey.bind(mash, '0', function() pom_disable() end)