Skip to content
This repository was archived by the owner on Apr 26, 2023. It is now read-only.

Commit 4f89007

Browse files
committed
Better "seconds remaining" text
1 parent 0b267a6 commit 4f89007

File tree

5 files changed

+69
-47
lines changed

5 files changed

+69
-47
lines changed

res/settings.ui

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@
427427
<string/>
428428
</property>
429429
<property name="readOnly">
430-
<bool>false</bool>
430+
<bool>true</bool>
431431
</property>
432432
</widget>
433433
<widget class="QLineEdit" name="undo_split_input">
@@ -477,9 +477,6 @@
477477
<property name="text">
478478
<string/>
479479
</property>
480-
<property name="frame">
481-
<bool>true</bool>
482-
</property>
483480
<property name="readOnly">
484481
<bool>true</bool>
485482
</property>

src/AutoSplit.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,9 @@ def __start_image_function(self):
300300
or not self.start_image \
301301
or time() < self.check_start_image_timestamp \
302302
or (not self.settings_dict["split_hotkey"] and not self.is_auto_controlled):
303-
pause_time_left = f"{self.check_start_image_timestamp - time():.1f}"
303+
pause_time_left = self.check_start_image_timestamp - time()
304304
self.current_split_image.setText(
305-
f"None\n (Paused before loading Start Image).\n {pause_time_left} sec remaining")
305+
f"None\n (Paused before loading Start Image).\n {seconds_remaining_text(pause_time_left)}")
306306
return
307307

308308
if self.check_start_image_timestamp > 0:
@@ -347,9 +347,9 @@ def __start_image_function(self):
347347
delay_start_time = time()
348348
start_delay = self.start_image.delay / 1000
349349
while time() - delay_start_time < start_delay:
350-
delay_time_left = round(start_delay - (time() - delay_start_time), 1)
350+
delay_time_left = start_delay - (time() - delay_start_time)
351351
self.current_split_image.setText(
352-
f"Delayed Before Starting:\n {delay_time_left} sec remaining")
352+
f"Delayed Before Starting:\n {seconds_remaining_text(delay_time_left)}")
353353
# Email sent to [email protected]
354354
QtTest.QTest.qWait(1) # type: ignore
355355

@@ -636,8 +636,8 @@ def __auto_splitter(self):
636636
# check for reset while delayed and display a counter of the remaining split delay time
637637
delay_start_time = time()
638638
while time() - delay_start_time < split_delay:
639-
delay_time_left = round(split_delay - (time() - delay_start_time), 1)
640-
self.current_split_image.setText(f"Delayed Split: {delay_time_left} sec remaining")
639+
delay_time_left = split_delay - (time() - delay_start_time)
640+
self.current_split_image.setText(f"Delayed Split: {seconds_remaining_text(delay_time_left)}")
641641
if self.__check_for_reset():
642642
return
643643

@@ -684,8 +684,8 @@ def __auto_splitter(self):
684684
if pause_time > 0:
685685
pause_start_time = time()
686686
while time() - pause_start_time < pause_time:
687-
pause_time_left = round(pause_time - (time() - pause_start_time), 1)
688-
self.current_split_image.setText(f"None (Paused). {pause_time_left} sec remaining")
687+
pause_time_left = pause_time - (time() - pause_start_time)
688+
self.current_split_image.setText(f"None (Paused). {seconds_remaining_text(pause_time_left)}")
689689

690690
if self.__check_for_reset():
691691
return
@@ -869,6 +869,10 @@ def exit_program():
869869
exit_program()
870870

871871

872+
def seconds_remaining_text(seconds: float):
873+
return f"{seconds:.1f} second{'' if 0 < seconds <= 1 else 's'} remaining"
874+
875+
872876
def main():
873877
# Call to QApplication outside the try-except so we can show error messages
874878
app = QApplication(sys.argv)

src/hotkeys.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
from AutoSplit import AutoSplit
77

88
import threading
9-
from keyboard._keyboard_event import KeyboardEvent, KEY_DOWN
9+
1010
import keyboard # https://github.com/boppreh/keyboard/issues/505
1111
import pyautogui # https://github.com/asweigart/pyautogui/issues/645
12-
# While not usually recommended, we don'thread manipulate the mouse, and we don'thread want the extra delay
12+
# While not usually recommended, we don't manipulate the mouse, and we don't want the extra delay
1313
pyautogui.FAILSAFE = False
1414

1515
SET_HOTKEY_TEXT = "Set Hotkey"
@@ -100,11 +100,11 @@ def _send_hotkey(key_or_scan_code: Union[int, str]):
100100
pyautogui.hotkey(key_or_scan_code.replace(" ", ""))
101101

102102

103-
def __validate_keypad(expected_key: str, keyboard_event: KeyboardEvent) -> bool:
103+
def __validate_keypad(expected_key: str, keyboard_event: keyboard.KeyboardEvent) -> bool:
104104
# Prevent "(keypad)delete", "(keypad)./decimal" and "del" from triggering each other
105105
# as well as "." and "(keypad)./decimal"
106106
if keyboard_event.scan_code in {83, 52}:
107-
# TODO: "del" won'thread work with "(keypad)delete" if localized in non-english (ie: "suppr" in french)
107+
# TODO: "del" won't work with "(keypad)delete" if localized in non-english (ie: "suppr" in french)
108108
return expected_key == keyboard_event.name
109109
# Prevent "action keys" from triggering "keypad keys"
110110
if keyboard_event.name and is_digit(keyboard_event.name[-1]):
@@ -125,16 +125,16 @@ def __validate_keypad(expected_key: str, keyboard_event: KeyboardEvent) -> bool:
125125

126126
# We're doing the check here instead of saving the key code because it'll
127127
# cause issues with save files and the non-keypad shared keys are localized
128-
# while the keypad ones aren'thread.
128+
# while the keypad ones aren't.
129129

130-
# Since we reuse the key string we set to send to LiveSplit, we can'thread use fake names like "num home".
130+
# Since we reuse the key string we set to send to LiveSplit, we can't use fake names like "num home".
131131
# We're also trying to achieve the same hotkey behaviour as LiveSplit has.
132-
def _hotkey_action(keyboard_event: KeyboardEvent, key_name: str, action: Callable[[], None]):
133-
if keyboard_event.event_type == KEY_DOWN and __validate_keypad(key_name, keyboard_event):
132+
def _hotkey_action(keyboard_event: keyboard.KeyboardEvent, key_name: str, action: Callable[[], None]):
133+
if keyboard_event.event_type == keyboard.KEY_DOWN and __validate_keypad(key_name, keyboard_event):
134134
action()
135135

136136

137-
def __get_key_name(keyboard_event: KeyboardEvent):
137+
def __get_key_name(keyboard_event: keyboard.KeyboardEvent):
138138
return f"num {keyboard_event.name}" \
139139
if keyboard_event.is_keypad and is_digit(keyboard_event.name) \
140140
else str(keyboard_event.name)

typings/keyboard/__init__.pyi

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ This type stub file was generated by pyright.
33
"""
44
from __future__ import print_function as _print_function
55
import typing
6+
import collections.abc
67

78
import re as _re
89
import itertools as _itertools
@@ -13,6 +14,7 @@ from threading import Lock as _Lock, Thread as _Thread
1314
from ._keyboard_event import KEY_DOWN, KEY_UP, KeyboardEvent
1415
from ._generic import GenericListener as _GenericListener
1516
from ._canonical_names import all_modifiers, normalize_name, sided_modifiers
17+
__all__ = ["all_modifiers", "normalize_name", "sided_modifiers", "KEY_DOWN", "KEY_UP", "KeyboardEvent"]
1618

1719
try:
1820
# Python2
@@ -103,12 +105,12 @@ key events. In this case `keyboard` will be unable to report events.
103105
- This program makes no attempt to hide itself, so don't use it for keyloggers or online gaming bots. Be responsible.
104106
"""
105107

106-
Callback = typing.Callable[[KeyboardEvent], None]
108+
Callback = collections.abc.Callable[[KeyboardEvent], None]
107109

108110
version: str
109-
_is_str = typing.Callable[[typing.Any], bool]
110-
_is_number = typing.Callable[[typing.Any], bool]
111-
_is_list: typing.Callable[[typing.Any], bool]
111+
_is_str = collections.abc.Callable[[typing.Any], bool]
112+
_is_number = collections.abc.Callable[[typing.Any], bool]
113+
_is_list: collections.abc.Callable[[typing.Any], bool]
112114

113115

114116
class _State:
@@ -120,10 +122,6 @@ class _Event(_UninterruptibleEvent):
120122
...
121123

122124

123-
if _platform.system() == 'Windows':
124-
...
125-
else:
126-
...
127125
_modifier_scan_codes: set
128126

129127

@@ -197,14 +195,16 @@ class _KeyboardListener(_GenericListener):
197195
_listener: _KeyboardListener
198196

199197

200-
def key_to_scan_codes(key: typing.Union[int, str, typing.List[typing.Union[int, str]]], error_if_missing: bool = ...) -> typing.List[int]:
198+
def key_to_scan_codes(key: typing.Union[int, str, typing.List[typing.Union[int, str]]],
199+
error_if_missing: bool = ...) -> typing.List[int]:
201200
"""
202201
Returns a list of scan codes associated with this key (name or scan code).
203202
"""
204203
...
205204

206205

207-
def parse_hotkey(hotkey) -> tuple[tuple[tuple[Unknown] | Unknown | tuple[()] | tuple[Unknown, ...]]] | tuple[tuple[tuple[Unknown] | Unknown | tuple[()] | tuple[Unknown, ...], ...]] | tuple[Unknown, ...]:
206+
def parse_hotkey(hotkey) -> tuple[tuple[tuple[Unknown] | Unknown | tuple[()] | tuple[Unknown, ...]]
207+
] | tuple[tuple[tuple[Unknown] | Unknown | tuple[()] | tuple[Unknown, ...], ...]] | tuple[Unknown, ...]:
208208
"""
209209
Parses a user-provided hotkey into nested tuples representing the
210210
parsed structure, with the bottom values being lists of scan codes.
@@ -274,10 +274,10 @@ def call_later(fn, args=..., delay=...) -> None:
274274
...
275275

276276

277-
_hooks: dict[typing.Callable, Unknown]
277+
_hooks: dict[collections.abc.Callable, Unknown]
278278

279279

280-
def hook(callback: Callback, suppress=..., on_remove=...) -> typing.Callable[[], None]:
280+
def hook(callback: Callback, suppress=..., on_remove=...) -> collections.abc.Callable[[], None]:
281281
"""
282282
Installs a global listener on all available keyboards, invoking `callback`
283283
each time a key is pressed or released.
@@ -296,21 +296,22 @@ def hook(callback: Callback, suppress=..., on_remove=...) -> typing.Callable[[],
296296
...
297297

298298

299-
def on_press(callback: Callback, suppress=...) -> typing.Callable[[], None]:
299+
def on_press(callback: Callback, suppress=...) -> collections.abc.Callable[[], None]:
300300
"""
301301
Invokes `callback` for every KEY_DOWN event. For details see `hook`.
302302
"""
303303
...
304304

305305

306-
def on_release(callback: Callback, suppress=...) -> typing.Callable[[], None]:
306+
def on_release(callback: Callback, suppress=...) -> collections.abc.Callable[[], None]:
307307
"""
308308
Invokes `callback` for every KEY_UP event. For details see `hook`.
309309
"""
310310
...
311311

312312

313-
def hook_key(key: typing.Union[int, str, typing.List[typing.Union[int, str]]], callback: Callback, suppress: bool = ...) -> typing.Callable[[], None]:
313+
def hook_key(key: typing.Union[int, str, typing.List[typing.Union[int, str]]],
314+
callback: Callback, suppress: bool = ...) -> collections.abc.Callable[[], None]:
314315
"""
315316
Hooks key up and key down events for a single key. Returns the event handler
316317
created. To remove a hooked key use `unhook_key(key)` or
@@ -322,21 +323,21 @@ def hook_key(key: typing.Union[int, str, typing.List[typing.Union[int, str]]], c
322323
...
323324

324325

325-
def on_press_key(key, callback: Callback, suppress=...) -> typing.Callable[[], None]:
326+
def on_press_key(key, callback: Callback, suppress=...) -> collections.abc.Callable[[], None]:
326327
"""
327328
Invokes `callback` for KEY_DOWN event related to the given key. For details see `hook`.
328329
"""
329330
...
330331

331332

332-
def on_release_key(key, callback: Callback, suppress=...) -> typing.Callable[[], None]:
333+
def on_release_key(key, callback: Callback, suppress=...) -> collections.abc.Callable[[], None]:
333334
"""
334335
Invokes `callback` for KEY_UP event related to the given key. For details see `hook`.
335336
"""
336337
...
337338

338339

339-
def unhook(remove: typing.Callable[[], None]) -> None:
340+
def unhook(remove: collections.abc.Callable[[], None]) -> None:
340341
"""
341342
Removes a previously added hook, either by callback or by the return value
342343
of `hook`.
@@ -355,7 +356,7 @@ def unhook_all() -> None:
355356
...
356357

357358

358-
def block_key(key) -> typing.Callable[[], None]:
359+
def block_key(key) -> collections.abc.Callable[[], None]:
359360
"""
360361
Suppresses all key events of the given key, regardless of modifiers.
361362
"""
@@ -365,7 +366,7 @@ def block_key(key) -> typing.Callable[[], None]:
365366
unblock_key = unhook_key
366367

367368

368-
def remap_key(src, dst) -> typing.Callable[[], None]:
369+
def remap_key(src, dst) -> collections.abc.Callable[[], None]:
369370
"""
370371
Whenever the key `src` is pressed or released, regardless of modifiers,
371372
press or release the hotkey `dst` instead.
@@ -388,7 +389,8 @@ def parse_hotkey_combinations(hotkey) -> tuple[tuple[tuple[Unknown, ...], ...],
388389
_hotkeys: dict
389390

390391

391-
def add_hotkey(hotkey, callback: Callback, args=..., suppress=..., timeout=..., trigger_on_release=...) -> typing.Callable[[], None]:
392+
def add_hotkey(hotkey, callback: collections.abc.Callable, args=..., suppress=..., timeout=...,
393+
trigger_on_release=...) -> collections.abc.Callable[[], None]:
392394
"""
393395
Invokes a callback every time a hotkey is pressed. The hotkey must
394396
be in the format `ctrl+shift+a, s`. This would trigger when the user holds
@@ -453,7 +455,7 @@ def unhook_all_hotkeys() -> None:
453455
unregister_all_hotkeys = remove_all_hotkeys = clear_all_hotkeys = unhook_all_hotkeys
454456

455457

456-
def remap_hotkey(src, dst, suppress=..., trigger_on_release=...) -> typing.Callable[[], None]:
458+
def remap_hotkey(src, dst, suppress=..., trigger_on_release=...) -> collections.abc.Callable[[], None]:
457459
"""
458460
Whenever the hotkey `src` is pressed, suppress it and send
459461
`dst` instead.
@@ -589,10 +591,11 @@ def get_typed_strings(events, allow_backspace=...):
589591
...
590592

591593

592-
_recording: typing.Optional[tuple[Unknown | _queue.Queue[Unknown], typing.Callable[[], None]]]
594+
_recording: typing.Optional[tuple[Unknown | _queue.Queue[Unknown], collections.abc.Callable[[], None]]]
593595

594596

595-
def start_recording(recorded_events_queue=...) -> tuple[Unknown | _queue.Queue[Unknown], typing.Callable[[], None]]:
597+
def start_recording(recorded_events_queue=...) -> tuple[Unknown
598+
| _queue.Queue[Unknown], collections.abc.Callable[[], None]]:
596599
"""
597600
Starts recording all keyboard events into a global variable, or the given
598601
queue if any. Returns the queue of events and the hooked function.
@@ -639,7 +642,13 @@ replay = play
639642
_word_listeners: dict
640643

641644

642-
def add_word_listener(word, callback: Callback, triggers=..., match_suffix=..., timeout=...) -> typing.Callable[[], None]:
645+
def add_word_listener(
646+
word,
647+
callback: Callback,
648+
triggers=...,
649+
match_suffix=...,
650+
timeout=...) -> collections.abc.Callable[[],
651+
None]:
643652
"""
644653
Invokes a callback every time a sequence of characters is typed (e.g. 'pet')
645654
and followed by a trigger key (e.g. space). Modifiers (e.g. alt, ctrl,
@@ -676,7 +685,8 @@ def remove_word_listener(word_or_handler) -> None:
676685
...
677686

678687

679-
def add_abbreviation(source_text, replacement_text, match_suffix=..., timeout=...) -> typing.Callable[[], None]:
688+
def add_abbreviation(source_text, replacement_text, match_suffix=...,
689+
timeout=...) -> collections.abc.Callable[[], None]:
680690
"""
681691
Registers a hotkey that replaces one typed text with another. For example
682692

typings/keyboard/_canonical_names.pyi

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"""
2+
This type stub file was generated by pyright.
3+
"""
4+
5+
canonical_names = ...
6+
sided_modifiers = ...
7+
all_modifiers = ...
8+
9+
10+
def normalize_name(name: str) -> str:
11+
...

0 commit comments

Comments
 (0)