Skip to content

Commit 8233767

Browse files
Refactor key event handling in SuraPlayer into a separate KeyHandler class.
1 parent 29358f9 commit 8233767

File tree

2 files changed

+100
-57
lines changed

2 files changed

+100
-57
lines changed

ui/sura_player_ui/key_handler.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
from PyQt6.QtGui import QKeyEvent
2+
from PyQt6.QtCore import Qt
3+
from utils.universal_speech import UniversalSpeech
4+
5+
6+
class KeyHandler:
7+
"""
8+
Handles keyboard events in the application, including arrow key actions and keyboard shortcuts.
9+
10+
This class separates key handling logic from the main window, making the code more modular and easier to maintain.
11+
"""
12+
13+
def __init__(self, parent):
14+
"""
15+
Initializes the KeyHandler with references to the parent window's functions and UI elements.
16+
17+
:param parent: The main application window (QMainWindow).
18+
"""
19+
self.parent = parent # Reference to the main window
20+
21+
# Mapping arrow keys to their respective functions
22+
self.arrow_actions = {
23+
Qt.Key_Left: parent.rewind,
24+
Qt.Key_Right: parent.forward
25+
}
26+
27+
# Mapping modifier keys to the corresponding time values for rewinding/forwarding
28+
self.arrow_modifiers = {
29+
Qt.ControlModifier | Qt.ShiftModifier: 60, # Ctrl + Shift -> 60 seconds
30+
Qt.ShiftModifier: 10, # Shift -> 10 seconds
31+
Qt.ControlModifier: 20, # Ctrl -> 20 seconds
32+
}
33+
34+
# Mapping shortcut keys to their corresponding actions
35+
self.shortcuts = {
36+
ord("E"): lambda: UniversalSpeech.say(parent.elapsed_time_label.text()),
37+
ord("R"): lambda: UniversalSpeech.say(parent.remaining_time_label.text()),
38+
ord("T"): lambda: UniversalSpeech.say(parent.total_time.text()),
39+
ord("C"): lambda: UniversalSpeech.say(parent.reciter_combo.currentText()),
40+
ord("V"): lambda: UniversalSpeech.say(parent.surah_combo.currentText()),
41+
ord("I"): lambda: UniversalSpeech.say(
42+
f"{parent.surah_combo.currentText()}, {parent.reciter_combo.currentText()}"
43+
),
44+
**{Qt.Key.Key_0 + i: lambda i=i: parent.set_position(i * 10, by_percent=True) for i in range(10)},
45+
Qt.Key_MediaTogglePlayPause: parent.toggle_play_pause,
46+
Qt.Key_MediaStop: parent.stop,
47+
Qt.Key_MediaPrevious: parent.previous_surah,
48+
Qt.Key_MediaNext: parent.next_surah,
49+
}
50+
51+
def handle_key_press(self, event: QKeyEvent) -> bool:
52+
"""
53+
Handles key press events by delegating to the appropriate method.
54+
55+
:param event: The key press event (QKeyEvent).
56+
:return: True if the event was handled, False otherwise.
57+
"""
58+
if self.process_arrows(event):
59+
return True
60+
61+
# Ignore unknown shortcuts if Ctrl, Shift, or Alt is held
62+
if event.modifiers() & (Qt.ControlModifier | Qt.ShiftModifier | Qt.AltModifier):
63+
return True
64+
65+
if self.process_shortcuts(event):
66+
return True
67+
68+
return False
69+
70+
def process_arrows(self, event: QKeyEvent) -> bool:
71+
"""
72+
Handles left and right arrow keys with different modifier combinations.
73+
74+
:param event: The key press event (QKeyEvent).
75+
:return: True if the event was handled, False otherwise.
76+
"""
77+
action = self.arrow_actions.get(event.key())
78+
if action:
79+
for modifier, value in self.arrow_modifiers.items():
80+
if event.modifiers() == modifier:
81+
action(value)
82+
return True
83+
return False
84+
85+
def process_shortcuts(self, event: QKeyEvent) -> bool:
86+
"""
87+
Handles predefined keyboard shortcuts for playback control and UI interactions.
88+
89+
:param event: The key press event (QKeyEvent).
90+
:return: True if the event was handled, False otherwise.
91+
"""
92+
key_code = event.nativeVirtualKey() or event.key()
93+
action = self.shortcuts.get(key_code)
94+
if action:
95+
action()
96+
return True
97+
return False

ui/sura_player_ui/sura_player_ui.py

Lines changed: 3 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from utils.user_data import PreferencesManager
2020
from utils.settings import SettingsManager
2121
from.menubar import MenuBar
22+
from .key_handler import KeyHandler
2223

2324

2425
class SuraPlayerWindow(QMainWindow):
@@ -34,8 +35,7 @@ def __init__(self, parent=None) -> None:
3435
self.player = SurahPlayer()
3536
self.audio_player_thread = AudioPlayerThread(self.player, self)
3637
self.filter_manager = FilterManager()
37-
self.filter_mode = False
38-
self.search_text = ""
38+
self.key_handler = KeyHandler(self)
3939

4040
central_widget = QWidget()
4141
layout = QVBoxLayout(central_widget)
@@ -415,61 +415,7 @@ def keyPressEvent(self, event: QKeyEvent):
415415
if self.filter_manager.handle_key_press(event):
416416
return
417417

418-
if event.key() == Qt.Key_Left:
419-
if event.modifiers() & (Qt.ControlModifier | Qt.ShiftModifier):
420-
self.rewind(60)
421-
elif event.modifiers() & Qt.ShiftModifier:
422-
self.rewind(10)
423-
elif event.modifiers() & Qt.ControlModifier:
424-
self.rewind(20)
425-
426-
elif event.key() == Qt.Key_Right:
427-
if event.modifiers() & (Qt.ControlModifier | Qt.ShiftModifier):
428-
self.forward(60)
429-
elif event.modifiers() & Qt.ShiftModifier:
430-
self.forward(10)
431-
elif event.modifiers() & Qt.ControlModifier:
432-
self.forward(20)
433-
434-
else:
435-
super().keyPressEvent(event)
436-
437-
438-
439-
440-
441-
if event.modifiers() & (Qt.ControlModifier | Qt.ShiftModifier | Qt.AltModifier):
442-
return
443-
444-
shortcuts = {
445-
ord("E"): lambda: UniversalSpeech.say(self.elapsed_time_label.text()),
446-
ord("R"): lambda: UniversalSpeech.say(self.remaining_time_label.text()),
447-
ord("T"): lambda: UniversalSpeech.say(self.total_time.text()),
448-
ord("C"): lambda: UniversalSpeech.say(self.reciter_combo.currentText()),
449-
ord("V"): lambda: UniversalSpeech.say(self.surah_combo.currentText()),
450-
ord("I"): lambda: UniversalSpeech.say(F"{self.surah_combo.currentText()}, {self.reciter_combo.currentText()}"),
451-
Qt.Key.Key_1: lambda: self.set_position(10, by_percent=True),
452-
Qt.Key.Key_2: lambda: self.set_position(20, by_percent=True),
453-
Qt.Key.Key_3: lambda: self.set_position(30, by_percent=True),
454-
Qt.Key.Key_4: lambda: self.set_position(40, by_percent=True),
455-
Qt.Key.Key_5: lambda: self.set_position(50, by_percent=True),
456-
Qt.Key.Key_6: lambda: self.set_position(60, by_percent=True),
457-
Qt.Key.Key_7: lambda: self.set_position(70, by_percent=True),
458-
Qt.Key.Key_8: lambda: self.set_position(80, by_percent=True),
459-
Qt.Key.Key_9: lambda: self.set_position(90, by_percent=True),
460-
Qt.Key.Key_0: lambda: self.set_position(0, by_percent=True),
461-
Qt.Key_MediaTogglePlayPause: lambda: self.toggle_play_pause(),
462-
Qt.Key_MediaStop: lambda: self.stop(),
463-
Qt.Key_MediaPrevious: lambda: self.previous_surah(),
464-
Qt.Key_MediaNext: lambda: self.next_surah(),
465-
}
466-
467-
key_native = event.nativeVirtualKey()
468-
if key_native in shortcuts:
469-
shortcuts[key_native]()
470-
return
471-
elif event.key() in shortcuts:
472-
shortcuts[event.key()]()
418+
if self.key_handler.handle_key_press(event):
473419
return
474420

475421
return super().keyPressEvent(event)

0 commit comments

Comments
 (0)