Skip to content

Commit ead0b9c

Browse files
committed
feat: Implement a settings GUI, configuration constants, and a settings manager, and integrate them into the main application.
1 parent ace4d2e commit ead0b9c

5 files changed

Lines changed: 350 additions & 54 deletions

File tree

core/config.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33
class Config:
44
# Visual Settings
55
SCROLL_SPEED = 800 # Pixels per second
6-
BAR_WIDTH = 60 # Width of a single note bar
6+
LANE_WIDTH = 70 # Horizontal spacing between lane starts
7+
BAR_WIDTH = LANE_WIDTH # Width of a single note bar (Gapless: Matches Lane Width)
78
BAR_HEIGHT = 20 # Visual thickness of the bar (does not affect timing)
89

10+
# KeyViewer
11+
KV_HEIGHT = 50 # Height of the KeyViewer bar
12+
913
# Lane Configuration
1014
# Maps key strings (pynput format) to lane indices (0-based)
1115
LANE_MAP = {
@@ -14,7 +18,7 @@ class Config:
1418
"'l'": 2,
1519
"';'": 3
1620
}
17-
LANE_WIDTH = 70 # Horizontal spacing between lane starts
21+
# LANE_WIDTH moved up to link with BAR_WIDTH
1822
LANE_START_X = 50 # Starting X offset for the first lane
1923

2024
# Performance & Logic
@@ -33,3 +37,5 @@ class Config:
3337
COLOR_BAR = QColor(100, 200, 255, 200)
3438
COLOR_BAR_BORDER = QColor(255, 255, 255, 230)
3539
COLOR_DEBUG_TEXT = QColor(0, 255, 0, 255)
40+
41+
VERSION = "1.1.1"

core/gui.py

Lines changed: 101 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QSpinBox, QComboBox, QGroupBox, QPushButton
1+
from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QSpinBox, QComboBox, QGroupBox, QPushButton, QCheckBox, QFrame, QColorDialog
22
from PySide6.QtCore import Qt, Slot
33
from PySide6.QtGui import QColor, QPalette
44
from .settings_manager import SettingsManager
@@ -45,15 +45,15 @@ def init_ui(self):
4545
vis_group = QGroupBox("Visual Settings")
4646
vis_layout = QVBoxLayout()
4747

48-
# Direction
49-
dir_layout = QHBoxLayout()
50-
dir_layout.addWidget(QLabel("Fall Direction:"))
51-
self.combo_dir = QComboBox()
52-
self.combo_dir.addItems(["down", "up"])
53-
self.combo_dir.setCurrentText(self.settings.fall_direction)
54-
self.combo_dir.currentTextChanged.connect(self.on_visual_changed)
55-
dir_layout.addWidget(self.combo_dir)
56-
vis_layout.addLayout(dir_layout)
48+
# Direction (REMOVED: Bound to Position)
49+
# dir_layout = QHBoxLayout()
50+
# dir_layout.addWidget(QLabel("Fall Direction:"))
51+
# self.combo_dir = QComboBox()
52+
# self.combo_dir.addItems(["down", "up"])
53+
# self.combo_dir.setCurrentText(self.settings.fall_direction)
54+
# self.combo_dir.currentTextChanged.connect(self.on_visual_changed)
55+
# dir_layout.addWidget(self.combo_dir)
56+
# vis_layout.addLayout(dir_layout)
5757

5858
# Speed
5959
speed_layout = QHBoxLayout()
@@ -66,6 +66,15 @@ def init_ui(self):
6666
speed_layout.addWidget(self.spin_speed)
6767
vis_layout.addLayout(speed_layout)
6868

69+
# Custom Color
70+
color_layout = QHBoxLayout()
71+
color_layout.addWidget(QLabel("Bar Color:"))
72+
self.btn_color = QPushButton("Choose Color")
73+
self.btn_color.clicked.connect(self.choose_color)
74+
self.update_color_btn_style()
75+
color_layout.addWidget(self.btn_color)
76+
vis_layout.addLayout(color_layout)
77+
6978
vis_group.setLayout(vis_layout)
7079
layout.addWidget(vis_group)
7180

@@ -87,6 +96,61 @@ def init_ui(self):
8796

8897
lane_group.setLayout(lane_layout)
8998
layout.addWidget(lane_group)
99+
100+
# KeyViewer Configuration Group
101+
kv_group = QGroupBox("KeyViewer Panel")
102+
kv_layout = QVBoxLayout()
103+
104+
self.chk_kv_enabled = QCheckBox("Enable KeyViewer")
105+
self.chk_kv_enabled.setChecked(self.settings.kv_enabled)
106+
self.chk_kv_enabled.stateChanged.connect(self.on_kv_changed)
107+
kv_layout.addWidget(self.chk_kv_enabled)
108+
109+
# Layout & Position
110+
kv_grid = QHBoxLayout()
111+
kv_grid.addWidget(QLabel("Height:"))
112+
self.spin_kv_height = QSpinBox()
113+
self.spin_kv_height.setRange(10, 500)
114+
self.spin_kv_height.setValue(self.settings.kv_height)
115+
self.spin_kv_height.valueChanged.connect(self.on_kv_changed)
116+
kv_grid.addWidget(self.spin_kv_height)
117+
118+
kv_grid.addWidget(QLabel("Pos:"))
119+
self.combo_kv_pos = QComboBox()
120+
self.combo_kv_pos.addItems(["below", "above"])
121+
# Handle removed 'auto' gracefully if config still has it
122+
current = self.settings.kv_position
123+
if current not in ["below", "above"]:
124+
current = "below"
125+
self.combo_kv_pos.setCurrentText(current)
126+
self.combo_kv_pos.currentTextChanged.connect(self.on_kv_changed)
127+
kv_grid.addWidget(self.combo_kv_pos)
128+
kv_layout.addLayout(kv_grid)
129+
130+
# Offsets
131+
off_layout = QHBoxLayout()
132+
off_layout.addWidget(QLabel("Offset X:"))
133+
self.spin_kv_off_x = QSpinBox()
134+
self.spin_kv_off_x.setRange(-1000, 1000)
135+
self.spin_kv_off_x.setValue(self.settings.kv_offset_x)
136+
self.spin_kv_off_x.valueChanged.connect(self.on_kv_changed)
137+
off_layout.addWidget(self.spin_kv_off_x)
138+
139+
off_layout.addWidget(QLabel("Y:"))
140+
self.spin_kv_off_y = QSpinBox()
141+
self.spin_kv_off_y.setRange(-1000, 1000)
142+
self.spin_kv_off_y.setValue(self.settings.kv_offset_y)
143+
self.spin_kv_off_y.valueChanged.connect(self.on_kv_changed)
144+
off_layout.addWidget(self.spin_kv_off_y)
145+
kv_layout.addLayout(off_layout)
146+
147+
self.chk_kv_counts = QCheckBox("Show Key Counts")
148+
self.chk_kv_counts.setChecked(self.settings.kv_show_counts)
149+
self.chk_kv_counts.stateChanged.connect(self.on_kv_changed)
150+
kv_layout.addWidget(self.chk_kv_counts)
151+
152+
kv_group.setLayout(kv_layout)
153+
layout.addWidget(kv_group)
90154

91155
layout.addStretch()
92156
self.setLayout(layout)
@@ -96,11 +160,37 @@ def on_pos_changed(self):
96160
self.settings.set('Position', 'y', self.spin_y.value())
97161
self.settings.save()
98162

163+
def choose_color(self):
164+
current = self.settings.bar_color
165+
color = QColorDialog.getColor(current, self, "Select Bar Color", QColorDialog.ShowAlphaChannel)
166+
if color.isValid():
167+
rgba = f"{color.red()},{color.green()},{color.blue()},{color.alpha()}"
168+
self.settings.set('Visual', 'bar_color', rgba)
169+
self.settings.save()
170+
self.update_color_btn_style()
171+
172+
def update_color_btn_style(self):
173+
c = self.settings.bar_color
174+
# Text color contrasting
175+
text_col = "black" if c.lightness() > 128 else "white"
176+
style = f"background-color: rgba({c.red()},{c.green()},{c.blue()},{c.alpha()}); color: {text_col};"
177+
self.btn_color.setStyleSheet(style)
178+
self.btn_color.setText(f"RGBA({c.red()},{c.green()},{c.blue()},{c.alpha()})")
179+
99180
def on_visual_changed(self):
100-
self.settings.set('Visual', 'fall_direction', self.combo_dir.currentText())
181+
# self.settings.set('Visual', 'fall_direction', self.combo_dir.currentText())
101182
self.settings.set('Visual', 'scroll_speed', self.spin_speed.value())
102183
self.settings.save()
103184

185+
def on_kv_changed(self):
186+
self.settings.set('keyviewer', 'enabled', self.chk_kv_enabled.isChecked())
187+
self.settings.set('keyviewer', 'height', self.spin_kv_height.value())
188+
self.settings.set('keyviewer', 'panel_position', self.combo_kv_pos.currentText())
189+
self.settings.set('keyviewer', 'panel_offset_x', self.spin_kv_off_x.value())
190+
self.settings.set('keyviewer', 'panel_offset_y', self.spin_kv_off_y.value())
191+
self.settings.set('keyviewer', 'show_counts', self.chk_kv_counts.isChecked())
192+
self.settings.save()
193+
104194
def toggle_recording(self):
105195
if not self.is_recording:
106196
# Start Recording

0 commit comments

Comments
 (0)