trainerbase 4.2.5__tar.gz → 4.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {trainerbase-4.2.5 → trainerbase-4.4.0}/LICENSE +2 -2
- {trainerbase-4.2.5 → trainerbase-4.4.0}/PKG-INFO +5 -5
- {trainerbase-4.2.5 → trainerbase-4.4.0}/pyproject.toml +3 -4
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gameobject.py +1 -7
- trainerbase-4.4.0/trainerbase/gui/misc.py +143 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/speedhack.py +30 -1
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/scriptengine.py +1 -1
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/speedhack.py +2 -7
- trainerbase-4.2.5/trainerbase/gui/misc.py +0 -80
- {trainerbase-4.2.5 → trainerbase-4.4.0}/.gitignore +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/README.md +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/__init__.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/abc.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/codeinjection.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/__init__.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/abc.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/helpers.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/keyboard.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/rainbow.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/tapper.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/common/teleport.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/config.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/__init__.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/helpers.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/injections.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/objects.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/rainbow.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/scripts.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/tapper.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/teleport.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/gui/types.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/logger.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/main.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/memory.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/process.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/py.typed +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase/tts.py +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase_vendor/FASM.EXE +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase_vendor/speedhack32.dll +0 -0
- {trainerbase-4.2.5 → trainerbase-4.4.0}/trainerbase_vendor/speedhack64.dll +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2021 -
|
|
4
|
-
Copyright (c) 2022 -
|
|
3
|
+
Copyright (c) 2021 - 2025 v01d
|
|
4
|
+
Copyright (c) 2022 - 2025 doomayka
|
|
5
5
|
|
|
6
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
7
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: trainerbase
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.0
|
|
4
4
|
Summary: Framework for creating game trainers/mods
|
|
5
5
|
Project-URL: Homepage, https://gitlab.com/python-trainers/
|
|
6
6
|
Project-URL: Repository, https://gitlab.com/python-trainers/trainer-base
|
|
7
7
|
Author-email: v01d <v01d@v01d.ru>, doomayka <zd@doomayka.ru>
|
|
8
|
-
License: MIT
|
|
9
|
-
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.13
|
|
11
11
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
12
12
|
Requires-Python: >=3.13
|
|
13
13
|
Requires-Dist: dearpygui>=2.0.0
|
|
14
14
|
Requires-Dist: keyboard>=0.13.5
|
|
15
15
|
Requires-Dist: mouse>=0.7.1
|
|
16
|
-
Requires-Dist: psutil>=6.1.
|
|
16
|
+
Requires-Dist: psutil>=6.1.1
|
|
17
17
|
Requires-Dist: pyinjector>=1.3.0
|
|
18
18
|
Requires-Dist: pymem>=1.14.0
|
|
19
19
|
Requires-Dist: pyttsx3>=2.98
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "trainerbase"
|
|
3
|
-
version = "4.
|
|
3
|
+
version = "4.4.0"
|
|
4
4
|
description = "Framework for creating game trainers/mods"
|
|
5
5
|
license = "MIT"
|
|
6
6
|
authors = [
|
|
@@ -13,7 +13,7 @@ dependencies = [
|
|
|
13
13
|
"dearpygui>=2.0.0",
|
|
14
14
|
"keyboard>=0.13.5",
|
|
15
15
|
"mouse>=0.7.1",
|
|
16
|
-
"psutil>=6.1.
|
|
16
|
+
"psutil>=6.1.1",
|
|
17
17
|
"pyinjector>=1.3.0",
|
|
18
18
|
"pymem>=1.14.0",
|
|
19
19
|
"pyttsx3>=2.98",
|
|
@@ -21,7 +21,6 @@ dependencies = [
|
|
|
21
21
|
|
|
22
22
|
classifiers = [
|
|
23
23
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
24
|
-
"Programming Language :: Python :: 3.12",
|
|
25
24
|
"Programming Language :: Python :: 3.13",
|
|
26
25
|
]
|
|
27
26
|
|
|
@@ -74,5 +73,5 @@ build-backend = "hatchling.build"
|
|
|
74
73
|
|
|
75
74
|
[dependency-groups]
|
|
76
75
|
dev = [
|
|
77
|
-
"ruff>=0.8.
|
|
76
|
+
"ruff>=0.8.6",
|
|
78
77
|
]
|
|
@@ -52,13 +52,7 @@ class GameObject[PymemType, TrainerBaseType](AbstractReadableObject[TrainerBaseT
|
|
|
52
52
|
self.value_range = value_range
|
|
53
53
|
|
|
54
54
|
def __repr__(self):
|
|
55
|
-
return (
|
|
56
|
-
f"<{self.__class__.__name__}"
|
|
57
|
-
f" at {hex(self.address.resolve())}:"
|
|
58
|
-
f" value={self.value},"
|
|
59
|
-
f" frozen={self.frozen}"
|
|
60
|
-
">"
|
|
61
|
-
)
|
|
55
|
+
return f"<{self.__class__.__name__} at {hex(self.address.resolve())}: value={self.value}, frozen={self.frozen}>"
|
|
62
56
|
|
|
63
57
|
def after_read(self, value: PymemType) -> TrainerBaseType:
|
|
64
58
|
return cast(TrainerBaseType, value)
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from typing import Any, override
|
|
3
|
+
|
|
4
|
+
from dearpygui import dearpygui as dpg
|
|
5
|
+
|
|
6
|
+
from trainerbase.common.keyboard import (
|
|
7
|
+
AbstractKeyboardHandler,
|
|
8
|
+
GameBoolReleaseHotkeySwitch,
|
|
9
|
+
ReleaseHotkeySwitch,
|
|
10
|
+
ShortLongHotkeyPressSwitch,
|
|
11
|
+
SimpleHotkeyHandler,
|
|
12
|
+
)
|
|
13
|
+
from trainerbase.gameobject import GameBool
|
|
14
|
+
from trainerbase.gui.helpers import add_components
|
|
15
|
+
from trainerbase.gui.objects import GameObjectUI
|
|
16
|
+
from trainerbase.gui.types import AbstractUIComponent
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class SeparatorUI(AbstractUIComponent):
|
|
20
|
+
def __init__(self, empty_lines_before: int = 1, empty_lines_after: int = 0):
|
|
21
|
+
self._empty_lines_before = empty_lines_before
|
|
22
|
+
self._empty_lines_after = empty_lines_after
|
|
23
|
+
|
|
24
|
+
@override
|
|
25
|
+
def add_to_ui(self) -> None:
|
|
26
|
+
for _ in range(self._empty_lines_before):
|
|
27
|
+
dpg.add_text()
|
|
28
|
+
|
|
29
|
+
dpg.add_separator()
|
|
30
|
+
|
|
31
|
+
for _ in range(self._empty_lines_after):
|
|
32
|
+
dpg.add_text()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class TextUI(AbstractUIComponent):
|
|
36
|
+
def __init__(self, text: str = ""):
|
|
37
|
+
self.text = text
|
|
38
|
+
|
|
39
|
+
@override
|
|
40
|
+
def add_to_ui(self) -> None:
|
|
41
|
+
dpg.add_text(self.text)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class HotkeyHandlerUI(AbstractUIComponent):
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
handler: AbstractKeyboardHandler,
|
|
48
|
+
label: str,
|
|
49
|
+
):
|
|
50
|
+
self.handler = handler
|
|
51
|
+
self.label = label
|
|
52
|
+
|
|
53
|
+
@override
|
|
54
|
+
def add_to_ui(self) -> None:
|
|
55
|
+
match self.handler:
|
|
56
|
+
case ShortLongHotkeyPressSwitch():
|
|
57
|
+
dpg.add_text(f"Press/Hold [{self.handler.hotkey}] Toggle/Enable {self.label}")
|
|
58
|
+
case ReleaseHotkeySwitch():
|
|
59
|
+
dpg.add_text(f"[{self.handler.hotkey}] Toggle {self.label}")
|
|
60
|
+
case SimpleHotkeyHandler():
|
|
61
|
+
dpg.add_button(
|
|
62
|
+
label=f"[{self.handler.hotkey}] {self.label}",
|
|
63
|
+
callback=self._ensure_callable_has_dunder_code(self.handler.callback),
|
|
64
|
+
)
|
|
65
|
+
case _:
|
|
66
|
+
dpg.add_text(f"[{self.handler.hotkey}] {self.label}")
|
|
67
|
+
|
|
68
|
+
self.handler.handle()
|
|
69
|
+
|
|
70
|
+
@staticmethod
|
|
71
|
+
def _ensure_callable_has_dunder_code(callable_object: Callable[[], None]) -> Callable[[], None]:
|
|
72
|
+
"""
|
|
73
|
+
DPG add_button has `callback` arg. In this case `callback.__code__` is required.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
if hasattr(callable, "__code__"):
|
|
77
|
+
callback_with_dunder_code = callable_object
|
|
78
|
+
else:
|
|
79
|
+
|
|
80
|
+
def callback_with_dunder_code():
|
|
81
|
+
callable_object()
|
|
82
|
+
|
|
83
|
+
return callback_with_dunder_code
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class HorizontalUI(AbstractUIComponent):
|
|
87
|
+
def __init__(self, *components: AbstractUIComponent):
|
|
88
|
+
self.components = components
|
|
89
|
+
|
|
90
|
+
@override
|
|
91
|
+
def add_to_ui(self) -> None:
|
|
92
|
+
with dpg.group(horizontal=True):
|
|
93
|
+
add_components(*self.components)
|
|
94
|
+
|
|
95
|
+
return super().add_to_ui()
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class SwitchableGameBoolUI(AbstractUIComponent):
|
|
99
|
+
def __init__(
|
|
100
|
+
self,
|
|
101
|
+
gameobject: GameBool,
|
|
102
|
+
toggle_hotkey: str,
|
|
103
|
+
label: str,
|
|
104
|
+
freeze_hotkey: str | None = None,
|
|
105
|
+
set_hotkey: str | None = None,
|
|
106
|
+
*,
|
|
107
|
+
default_setter_input_value: Any = 0,
|
|
108
|
+
before_set: Callable | None = None,
|
|
109
|
+
tts_on_hotkey: bool = True,
|
|
110
|
+
setter_input_width: int = 220,
|
|
111
|
+
toggle_text: str = "Toggle",
|
|
112
|
+
):
|
|
113
|
+
self.gameobject = gameobject
|
|
114
|
+
self.toggle_hotkey = toggle_hotkey
|
|
115
|
+
self.toggle_text = toggle_text
|
|
116
|
+
|
|
117
|
+
self.pure_label = label
|
|
118
|
+
self.freeze_hotkey = freeze_hotkey
|
|
119
|
+
self.set_hotkey = set_hotkey
|
|
120
|
+
self.default_setter_input_value = default_setter_input_value
|
|
121
|
+
self.before_set = before_set
|
|
122
|
+
self.tts_on_hotkey = tts_on_hotkey
|
|
123
|
+
self.setter_input_width = setter_input_width
|
|
124
|
+
|
|
125
|
+
@override
|
|
126
|
+
def add_to_ui(self) -> None:
|
|
127
|
+
add_components(
|
|
128
|
+
HorizontalUI(
|
|
129
|
+
HotkeyHandlerUI(GameBoolReleaseHotkeySwitch(self.gameobject, self.toggle_hotkey), self.toggle_text),
|
|
130
|
+
GameObjectUI(
|
|
131
|
+
self.gameobject,
|
|
132
|
+
self.pure_label,
|
|
133
|
+
self.freeze_hotkey,
|
|
134
|
+
self.set_hotkey,
|
|
135
|
+
default_setter_input_value=self.default_setter_input_value,
|
|
136
|
+
before_set=self.before_set,
|
|
137
|
+
tts_on_hotkey=self.tts_on_hotkey,
|
|
138
|
+
setter_input_width=self.setter_input_width,
|
|
139
|
+
),
|
|
140
|
+
)
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
return super().add_to_ui()
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
from functools import partial
|
|
1
2
|
from typing import override
|
|
2
3
|
|
|
3
4
|
from dearpygui import dearpygui as dpg
|
|
4
5
|
|
|
5
|
-
from trainerbase.common.keyboard import ShortLongHotkeyPressSwitch, Switchable
|
|
6
|
+
from trainerbase.common.keyboard import ShortLongHotkeyPressSwitch, SimpleHotkeyHandler, Switchable
|
|
6
7
|
from trainerbase.gui.helpers import add_components
|
|
7
8
|
from trainerbase.gui.misc import HotkeyHandlerUI
|
|
8
9
|
from trainerbase.gui.types import AbstractUIComponent
|
|
@@ -34,9 +35,15 @@ class SpeedHackUI(AbstractUIComponent):
|
|
|
34
35
|
speedhack: SpeedHack | None = None,
|
|
35
36
|
key: str = "Delete",
|
|
36
37
|
default_factor_input_value: float = 3.0,
|
|
38
|
+
next_preset_hotkey: str | None = "Shift+PageUp",
|
|
39
|
+
previous_preset_hotkey: str | None = "Shift+PageDown",
|
|
37
40
|
):
|
|
38
41
|
self.speedhack = SpeedHack() if speedhack is None else speedhack
|
|
42
|
+
|
|
39
43
|
self.key = key
|
|
44
|
+
self.next_preset_hotkey = next_preset_hotkey
|
|
45
|
+
self.previous_preset_hotkey = previous_preset_hotkey
|
|
46
|
+
|
|
40
47
|
self.default_factor_input_value = default_factor_input_value
|
|
41
48
|
self.handler = ShortLongHotkeyPressSwitch(
|
|
42
49
|
SpeedHackUISwitch(self.speedhack, self.DPG_TAG_SPEEDHACK_FACTOR_INPUT),
|
|
@@ -47,6 +54,19 @@ class SpeedHackUI(AbstractUIComponent):
|
|
|
47
54
|
def add_to_ui(self) -> None:
|
|
48
55
|
add_components(HotkeyHandlerUI(self.handler, "SpeedHack"))
|
|
49
56
|
|
|
57
|
+
if self.next_preset_hotkey is not None and self.previous_preset_hotkey is not None:
|
|
58
|
+
with dpg.group(horizontal=True):
|
|
59
|
+
add_components(
|
|
60
|
+
HotkeyHandlerUI(
|
|
61
|
+
SimpleHotkeyHandler(partial(self.change_preset, -1), self.previous_preset_hotkey),
|
|
62
|
+
"Preset -",
|
|
63
|
+
),
|
|
64
|
+
HotkeyHandlerUI(
|
|
65
|
+
SimpleHotkeyHandler(partial(self.change_preset, 1), self.next_preset_hotkey),
|
|
66
|
+
"Preset +",
|
|
67
|
+
),
|
|
68
|
+
)
|
|
69
|
+
|
|
50
70
|
dpg.add_input_double(
|
|
51
71
|
tag=self.DPG_TAG_SPEEDHACK_FACTOR_INPUT,
|
|
52
72
|
label="SpeedHack Factor",
|
|
@@ -68,6 +88,15 @@ class SpeedHackUI(AbstractUIComponent):
|
|
|
68
88
|
callback=self.on_preset_change,
|
|
69
89
|
)
|
|
70
90
|
|
|
91
|
+
def change_preset(self, diff: int):
|
|
92
|
+
new_preset_index = dpg.get_value(self.DPG_TAG_SPEEDHACK_PRESET_INPUT) + diff
|
|
93
|
+
|
|
94
|
+
if not (0 <= new_preset_index < len(self.PRESETS)):
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
dpg.set_value(self.DPG_TAG_SPEEDHACK_PRESET_INPUT, new_preset_index)
|
|
98
|
+
self.on_preset_change()
|
|
99
|
+
|
|
71
100
|
def on_preset_change(self):
|
|
72
101
|
new_factor = self.PRESETS[dpg.get_value(self.DPG_TAG_SPEEDHACK_PRESET_INPUT)]
|
|
73
102
|
dpg.set_value(self.DPG_TAG_SPEEDHACK_FACTOR_INPUT, new_factor)
|
|
@@ -36,7 +36,7 @@ class SimpleScript(AbstractBaseScript):
|
|
|
36
36
|
self.enabled = enabled
|
|
37
37
|
|
|
38
38
|
def __repr__(self):
|
|
39
|
-
return f"<Script {getattr(self._callback,
|
|
39
|
+
return f"<Script {getattr(self._callback, '__name__', 'Anon function-based script')}: enabled={self.enabled}>"
|
|
40
40
|
|
|
41
41
|
@override
|
|
42
42
|
def __call__(self):
|
|
@@ -4,11 +4,9 @@ from typing import Final, Self, cast
|
|
|
4
4
|
|
|
5
5
|
from pyinjector import inject
|
|
6
6
|
from pymem.exception import MemoryWriteError
|
|
7
|
-
from pymem.process import module_from_name
|
|
8
|
-
from pymem.ressources.structure import MODULEINFO
|
|
9
7
|
|
|
10
8
|
from trainerbase.gameobject import GameDouble
|
|
11
|
-
from trainerbase.memory import ARCH
|
|
9
|
+
from trainerbase.memory import ARCH, get_module_address
|
|
12
10
|
from trainerbase.process import pm
|
|
13
11
|
|
|
14
12
|
|
|
@@ -36,10 +34,7 @@ class SpeedHack:
|
|
|
36
34
|
|
|
37
35
|
def _inject(self) -> int:
|
|
38
36
|
inject(cast(int, pm.process_id), str(SPEEDHACK_DLL_PATH))
|
|
39
|
-
|
|
40
|
-
speedhack_address = cast(MODULEINFO, module_from_name(pm.process_handle, SPEEDHACK_DLL_MODULE_NAME)).lpBaseOfDll
|
|
41
|
-
|
|
42
|
-
return speedhack_address
|
|
37
|
+
return get_module_address(SPEEDHACK_DLL_MODULE_NAME)
|
|
43
38
|
|
|
44
39
|
@property
|
|
45
40
|
def factor(self):
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
2
|
-
from typing import override
|
|
3
|
-
|
|
4
|
-
from dearpygui import dearpygui as dpg
|
|
5
|
-
|
|
6
|
-
from trainerbase.common.keyboard import (
|
|
7
|
-
AbstractKeyboardHandler,
|
|
8
|
-
ReleaseHotkeySwitch,
|
|
9
|
-
ShortLongHotkeyPressSwitch,
|
|
10
|
-
SimpleHotkeyHandler,
|
|
11
|
-
)
|
|
12
|
-
from trainerbase.gui.types import AbstractUIComponent
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class SeparatorUI(AbstractUIComponent):
|
|
16
|
-
def __init__(self, empty_lines_before: int = 1, empty_lines_after: int = 0):
|
|
17
|
-
self._empty_lines_before = empty_lines_before
|
|
18
|
-
self._empty_lines_after = empty_lines_after
|
|
19
|
-
|
|
20
|
-
@override
|
|
21
|
-
def add_to_ui(self) -> None:
|
|
22
|
-
for _ in range(self._empty_lines_before):
|
|
23
|
-
dpg.add_text()
|
|
24
|
-
|
|
25
|
-
dpg.add_separator()
|
|
26
|
-
|
|
27
|
-
for _ in range(self._empty_lines_after):
|
|
28
|
-
dpg.add_text()
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class TextUI(AbstractUIComponent):
|
|
32
|
-
def __init__(self, text: str = ""):
|
|
33
|
-
self.text = text
|
|
34
|
-
|
|
35
|
-
@override
|
|
36
|
-
def add_to_ui(self) -> None:
|
|
37
|
-
dpg.add_text(self.text)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
class HotkeyHandlerUI(AbstractUIComponent):
|
|
41
|
-
def __init__(
|
|
42
|
-
self,
|
|
43
|
-
handler: AbstractKeyboardHandler,
|
|
44
|
-
label: str,
|
|
45
|
-
):
|
|
46
|
-
self.handler = handler
|
|
47
|
-
self.label = label
|
|
48
|
-
|
|
49
|
-
@override
|
|
50
|
-
def add_to_ui(self) -> None:
|
|
51
|
-
match self.handler:
|
|
52
|
-
case ShortLongHotkeyPressSwitch():
|
|
53
|
-
dpg.add_text(f"Hold [{self.handler.hotkey}] Enable {self.label}")
|
|
54
|
-
dpg.add_text(f"Press [{self.handler.hotkey}] Toggle {self.label}")
|
|
55
|
-
case ReleaseHotkeySwitch():
|
|
56
|
-
dpg.add_text(f"[{self.handler.hotkey}] Toggle {self.label}")
|
|
57
|
-
case SimpleHotkeyHandler():
|
|
58
|
-
dpg.add_button(
|
|
59
|
-
label=f"[{self.handler.hotkey}] {self.label}",
|
|
60
|
-
callback=self._ensure_callable_has_dunder_code(self.handler.callback),
|
|
61
|
-
)
|
|
62
|
-
case _:
|
|
63
|
-
dpg.add_text(f"[{self.handler.hotkey}] {self.label}")
|
|
64
|
-
|
|
65
|
-
self.handler.handle()
|
|
66
|
-
|
|
67
|
-
@staticmethod
|
|
68
|
-
def _ensure_callable_has_dunder_code(callable_object: Callable[[], None]) -> Callable[[], None]:
|
|
69
|
-
"""
|
|
70
|
-
DPG add_button has `callback` arg. In this case `callback.__code__` is required.
|
|
71
|
-
"""
|
|
72
|
-
|
|
73
|
-
if hasattr(callable, "__code__"):
|
|
74
|
-
callback_with_dunder_code = callable_object
|
|
75
|
-
else:
|
|
76
|
-
|
|
77
|
-
def callback_with_dunder_code():
|
|
78
|
-
callable_object()
|
|
79
|
-
|
|
80
|
-
return callback_with_dunder_code
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|