Skip to content

Commit

Permalink
[feat] Min/Max buttons on the home screen (#22)
Browse files Browse the repository at this point in the history
* Update dependencies

* Improve styling of sliders and buttons
  • Loading branch information
Lawstorant authored Sep 21, 2024
1 parent f8c9334 commit 5cbeb86
Show file tree
Hide file tree
Showing 21 changed files with 141 additions and 68 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Boxflat for Moza Racing. Control your Moza gear settings!

| Device | Completeness | WIP |
| :------------: | :----------: | :-- |
| Home page | 70% | Pedals min/max |
| Home page | 100% | |
| Base | 100% | |
| Wheel | 100% | |
| Pedals | 100% | |
Expand Down Expand Up @@ -59,11 +59,13 @@ https://aur.archlinux.org/packages/boxflat-git
This package depends on:
- python3
- gtk4
- libadwaita ~>1.3
- pyyaml 6.0.1
- libadwaita 1.6

Python dependencies:
- pyyaml 6.0.2
- pyserial 3.5
- pycairo 1.26.1
- PyGObject 3.48.2
- pycairo 1.27.0
- PyGObject 3.50.0
- evdev 1.7.1


Expand Down
2 changes: 1 addition & 1 deletion boxflat/panels/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def prepare_ui(self) -> None:
self._current_row.subscribe(self._cm.set_setting_int, "base-speed-damping")
self._append_sub("base-speed-damping", self._current_row.set_value)

self._add_row(BoxflatSliderRow("Speed-depended Damping", range_end=400, subtitle="KPH"))
self._add_row(BoxflatSliderRow("Speed-depended Damping", range_end=400, suffix=" kph "))
self._current_row.add_marks(120)
self._current_row.subscribe(self._cm.set_setting_int, "base-speed-damping-point")
self._append_sub("base-speed-damping-point", self._current_row.set_value)
Expand Down
8 changes: 4 additions & 4 deletions boxflat/panels/handbrake.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,16 @@ def prepare_ui(self) -> None:
self._add_row(BoxflatSliderRow("Range Start", suffix="%"))
self._current_row.add_marks(20, 40, 60, 80)
self._current_row.set_width(380)
self._current_row.subscribe(self._cm.set_setting_int, "handbrake-range-start")
self._current_row.subscribe(self._cm.set_setting_int, "handbrake-min")
# self._current_row.subscribe(self._current_group.set_range_start)
self._append_sub("handbrake-range-start", self._current_row.set_value)
self._append_sub("handbrake-min", self._current_row.set_value)

self._add_row(BoxflatSliderRow("Range End", suffix="%", value=100))
self._current_row.add_marks(20, 40, 60, 80)
self._current_row.set_width(380)
self._current_row.subscribe(self._cm.set_setting_int, "handbrake-range-end")
self._current_row.subscribe(self._cm.set_setting_int, "handbrake-max")
# self._current_row.subscribe(self._current_group.set_range_end)
self._append_sub("handbrake-range-end", self._current_row.set_value)
self._append_sub("handbrake-max", self._current_row.set_value)

self.add_preferences_group("Calibration")
self._add_row(BoxflatCalibrationRow("Handbrake Calibration", "Pull handbrake fully once"))
Expand Down
15 changes: 11 additions & 4 deletions boxflat/panels/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ def prepare_ui(self) -> None:
self._steer_row.set_suffix("°")
self._steer_row.set_subtitle(f"Limit = {self._rotation*2}°")
self._append_sub_hid(MozaAxis.STEERING, self._set_steering)
self._steer_row.set_value(0)

self._add_row(BoxflatButtonRow("Adjust center point", "Center"))
self._current_row.subscribe(self._cm.set_setting_int, "base-calibration")
Expand All @@ -34,18 +33,23 @@ def prepare_ui(self) -> None:
self.add_preferences_group("Pedals")
self._append_sub_connected("pedals-throttle-dir", self._current_group.set_active, 1)

self._add_row(BoxflatLevelRow("Throttle input", max_value=65534))
self._add_row(BoxflatMinMaxLevelRow("Throttle input", self._set_limit, "pedals-throttle", max_value=65534))
self._append_sub_hid(MozaAxis.THROTTLE, self._current_row.set_value)
self._append_sub_connected("pedals-throttle-dir", self._current_row.set_active, 1)

self._add_row(BoxflatLevelRow("Brake input", max_value=65534))
self._add_row(BoxflatMinMaxLevelRow("Brake input", self._set_limit, "pedals-brake", max_value=65534))
self._append_sub_hid(MozaAxis.BRAKE, self._current_row.set_value)
self._append_sub_connected("pedals-throttle-dir", self._current_row.set_active, 1)

self._add_row(BoxflatLevelRow("Clutch input", max_value=65534))
self._add_row(BoxflatMinMaxLevelRow("Clutch input", self._set_limit, "pedals-clutch", max_value=65534))
self._append_sub_hid(MozaAxis.CLUTCH, self._current_row.set_value)
self._append_sub_connected("pedals-throttle-dir", self._current_row.set_active, 1)

self.add_preferences_group("Handbrake")
self._add_row(BoxflatMinMaxLevelRow("Input", self._set_limit, "handbrake", max_value=65534))
self._append_sub_hid(MozaAxis.HANDBRAKE, self._current_row.set_value)
self._append_sub_connected("handbrake-direction", self._current_group.set_present, 1)


self.add_preferences_group("About")
self._add_row(BoxflatLabelRow("Version:", value=self._version))
Expand All @@ -72,3 +76,6 @@ def _set_steering(self, value: int) -> None:
self._steer_row.set_value(round((value - 32768) / 32768 * self._rotation))


def _set_limit(self, percent_func: callable, command: str):
# print(f"{command}: {percent_func()}")
self._cm.set_setting_int(percent_func(), command)
2 changes: 1 addition & 1 deletion boxflat/panels/others.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def prepare_ui(self) -> None:
self._add_row(BoxflatButtonRow("Refresh Devices", "Refresh", subtitle="Not necessary normally"))
self._current_row.subscribe(self._cm.device_discovery)

self._add_row(BoxflatSliderRow("HID Update Rate", suffix=" Hz", range_start=20, range_end=240, increment=10))
self._add_row(BoxflatSliderRow("HID Update Rate", suffix=" Hz ", range_start=20, range_end=240, increment=10))
self._current_row.add_marks(120)
self._current_row.subscribe(self._hid_handler.set_update_rate)
self._current_row.set_value(self._hid_handler.get_update_rate())
Expand Down
24 changes: 15 additions & 9 deletions boxflat/panels/presets.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,25 @@ def prepare_ui(self) -> None:
self._append_sub_connected("handbrake-direction", row.set_active, 1, True)
self._includes["handbrake"] = row.get_value

self._save_row = BoxflatButtonRow("Save preset", "Save")
self._save_row = Adw.ButtonRow(title="Save")
self._save_row.add_css_class("suggested-action")
self._save_row.set_end_icon_name("document-save-symbolic")
self._add_row(self._save_row)
self._current_row.subscribe(self._save_preset)
self._current_row.subscribe(lambda v: expander.set_expanded(False))
self._current_row.set_active(False)
self._name_row.connect("notify::text-length", lambda e, *args: self._save_row.set_active(e.get_text_length()))
self._save_row.connect("activated", self._save_preset)
self._save_row.connect("activated", lambda v: expander.set_expanded(False))
self._name_row.connect("notify::text-length", lambda e, *args: self._save_row.set_sensitive(e.get_text_length()))
self._save_row.set_sensitive(False)


def _save_preset(self, button: Gtk.Button, *args):
def _save_preset(self, button: Adw.ButtonRow):
self.show_toast(f"Saving preset \"{self._name_row.get_text()}\"", 1.5)
self._save_row.set_active(False)
self._save_row.set_sensitive(False)

pm = MozaPresetHandler(self._cm)
pm.set_path(self._presets_path)
pm.set_name(self._name_row.get_text())
pm.add_callback(self.list_presets)
pm.add_callback(self._save_row.set_active)
pm.add_callback(self._activate_save)

for key, method in self._includes.items():
if method():
Expand All @@ -85,6 +87,10 @@ def _save_preset(self, button: Gtk.Button, *args):
pm.save_preset()


def _activate_save(self):
GLib.idle_add(self._save_row.set_sensitive, True)


def _load_preset(self, preset_name: str, *args):
print(f"\nLoading preset {preset_name}")

Expand Down Expand Up @@ -126,7 +132,7 @@ def list_presets(self):
if os.path.isfile(filepath):
row = BoxflatButtonRow(file.removesuffix(".yml"))
row.add_button("Load", self._load_preset, file)
row.add_button("Delete")
row.add_button("Delete").add_css_class("destructive-action")
row.subscribe(self._delete_preset, file)
self._add_row(row)

Expand Down
1 change: 1 addition & 0 deletions boxflat/panels/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def __init__(self, button_callback: callable, connection_manager: MozaConnection
self._test_thread = Thread(daemon=True, target=self._wheel_rpm_test)
self._test_event = Event()
self._test_thread.start()
# TODO: rewrite threads so they are not persistent


def active(self, value: int) -> None:
Expand Down
4 changes: 2 additions & 2 deletions boxflat/preset_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@
"handbrake-direction",
"handbrake-mode",
"handbrake-button-threshold",
"handbrake-range-start",
"handbrake-range-end",
"handbrake-min",
"handbrake-max",
"handbrake-y1",
"handbrake-y2",
"handbrake-y3",
Expand Down
2 changes: 2 additions & 0 deletions boxflat/widgets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@
from .dialog_row import *
from .label_row import *
from .level_row import *
from .button_level_row import *
from .min_max_level_row import *
31 changes: 31 additions & 0 deletions boxflat/widgets/button_level_row.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from .level_row import *
from .button_row import *

import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk

class BoxflatButtonLevelRow(BoxflatLevelRow):
def __init__(self, title: str, subtitle="", max_value=1000):
super().__init__(title, subtitle, max_value, append_widget=False)

self._box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
# self._box.set_hexpand(True)
self._set_widget(self._box)
self._bar.set_margin_start(10)
self._bar.set_margin_end(0)


def add_button(self, button_label: str, callback: callable, *args):
button = Gtk.Button(label=button_label)
button.set_valign(Gtk.Align.CENTER)
button.set_margin_start(10)
self._box.append(button)
button.add_css_class("level-button")

button.connect('clicked', lambda button: callback(*args))


def insert_bar_now(self):
if not self._bar.get_parent():
self._box.append(self._bar)
7 changes: 5 additions & 2 deletions boxflat/widgets/button_row.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ def __init__(self, title: str, button_label: str=None, subtitle=""):
super().__init__(title, subtitle)

self._box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self._box.add_css_class("linked")
self._set_widget(self._box)

if button_label:
Expand All @@ -18,13 +19,15 @@ def get_value(self) -> int:
return round(eval("1" + self._expression))


def add_button(self, button_label: str, callback: callable=None, *args):
def add_button(self, button_label: str, callback: callable=None, *args) -> Gtk.Button:
button = Gtk.Button(label=button_label)
button.set_valign(Gtk.Align.CENTER)
button.set_margin_start(10)
# button.set_margin_start(10)
self._box.append(button)

if callback:
button.connect('clicked', lambda button: callback(*args))
else:
button.connect('clicked', lambda button: self._notify())

return button
1 change: 1 addition & 0 deletions boxflat/widgets/equalizer_row.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def __init__(self, title: str, sliders_number: int,
if button_row:
self._box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self._box.add_css_class("eq-buttons")
self._box.add_css_class("linked")
main_box.append(self._box)

main_box.append(sliders_box)
Expand Down
17 changes: 13 additions & 4 deletions boxflat/widgets/level_row.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk, GLib
from .row import BoxflatRow
from math import ceil
from math import ceil, floor

class BoxflatLevelRow(BoxflatRow):
def __init__(self, title: str, subtitle="", max_value=1000):
def __init__(self, title: str, subtitle="", max_value=1000, append_widget=True):
super().__init__(title, subtitle)

self._max_value = max_value
Expand All @@ -16,14 +16,15 @@ def __init__(self, title: str, subtitle="", max_value=1000):
bar.set_min_value(0)
bar.set_max_value(max_value)
bar.set_value(0)
bar.add_css_class("level-dark")
bar.set_margin_end(2)

bar.remove_offset_value(Gtk.LEVEL_BAR_OFFSET_LOW)
bar.remove_offset_value(Gtk.LEVEL_BAR_OFFSET_HIGH)
bar.remove_offset_value(Gtk.LEVEL_BAR_OFFSET_FULL)

self._set_widget(bar)
self._bar = bar
if append_widget:
self._set_widget(bar)

self.set_bar_width(310)
self._present_cooldown = True
Expand Down Expand Up @@ -68,3 +69,11 @@ def set_present(self, value, additional=0,
def set_active(self, value, offset=0) -> None:
if not super().set_active(value, offset):
self.set_value(0)


def get_value(self) -> int:
return int(self._bar.get_value())


def get_percent(self) -> int:
return floor((self._bar.get_value() * 100) / self._bar.get_max_value())
11 changes: 11 additions & 0 deletions boxflat/widgets/min_max_level_row.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from .button_level_row import *

class BoxflatMinMaxLevelRow(BoxflatButtonLevelRow):
def __init__(self, title: str, callback: callable,
command_prefix: str, subtitle="", max_value=1000):
super().__init__(title, subtitle, max_value)

self.set_bar_width(230)
self.add_button("Min", callback, self.get_percent, f"{command_prefix}-min")
self.insert_bar_now()
self.add_button("Max", callback, self.get_percent, f"{command_prefix}-max")
1 change: 1 addition & 0 deletions boxflat/widgets/slider_row.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def __init__(self, title="", range_start=0,
box.set_valign(Gtk.Align.CENTER)
else:
self.add_suffix(slider)
slider.add_css_class("slider")


# def _slider_increment_handler(self, scale) -> None:
Expand Down
3 changes: 2 additions & 1 deletion boxflat/widgets/toggle_button_row.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ def __init__(self, title: str, subtitle=""):
self._group = None
self._buttons = []

self._box.add_css_class("linked")


def add_buttons(self, *labels: str) -> None:
for label in labels:
button = Gtk.ToggleButton(label=label)
button.add_css_class("toggle-button")
button.set_valign(Gtk.Align.CENTER)
self._box.append(button)
self._buttons.append(button)
Expand Down
4 changes: 2 additions & 2 deletions data/serial.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1252,14 +1252,14 @@ commands:
bytes: 2
type: int

handbrake-range-start:
handbrake-min:
read: 91
write: 92
id: [2]
bytes: 2
type: int

handbrake-range-end:
handbrake-max:
read: 91
write: 92
id: [3]
Expand Down
Loading

0 comments on commit 5cbeb86

Please sign in to comment.