Files
Modus/mine/modules/osd/components/brightness.py
T
2026-07-12 18:56:10 +05:45

108 lines
4.0 KiB
Python

from fabric.widgets.image import Image
from fabric.widgets.scale import ScaleMark
from fabric.widgets.wayland import WaylandWindow as Window
from modules.osd.components.animated_scale import AnimatedScale
from modules.osd.components.base import BaseOSDContainer
from services import Brightness
class BrightnessOSDContainer(BaseOSDContainer):
def __init__(self, window: Window, **kwargs):
super().__init__(window, **kwargs)
self.brightness = Brightness.get_initial()
self._last_brightness = None # Track to avoid duplicate updates
self._setup_specific_components()
self._connect_specific_signals()
def _setup_specific_components(self):
self.icon = Image(icon_name="display-brightness-symbolic", icon_size=26)
current_brightness = self.brightness.screen_brightness
brightness_percentage = (
int((current_brightness / self.brightness.max_screen) * 100)
if self.brightness.max_screen > 0
else 50
)
self._last_brightness = brightness_percentage
self.scale = AnimatedScale(
marks=(ScaleMark(value=i) for i in range(1, 100, 10)),
value=brightness_percentage,
min_value=0,
max_value=100,
inverted=False,
increments=(1, 1),
orientation=self.get_orientation(),
on_state_flags_changed=lambda sc, *_: (
self.unfocus() if not (sc.get_state_flags() & 2) else None
),
on_value_changed=lambda *_: self.is_hovered() and self._update_brightness(),
)
self.children = self.icon, self.scale
def _connect_specific_signals(self):
self.brightness.connect(
"brightness_changed",
self._on_brightness_changed,
)
def _on_brightness_changed(self, _, value):
"""Handle brightness changes from the service."""
if self.is_hovered():
# User is interacting with the slider, don't update
return
brightness_percentage = int((value / self.brightness.max_screen) * 100)
# Only update if brightness actually changed
if (
self._last_brightness is None
or abs(brightness_percentage - self._last_brightness) > 0
):
self._last_brightness = brightness_percentage
self._update_icon(brightness_percentage)
self.scale.animate_value(brightness_percentage)
self.show_brightness_osd()
def show_brightness_osd(self):
"""Trigger the OSD to show the brightness container."""
if self.osd:
self.osd.show_brightness_osd()
else:
self.update()
def _update_icon(self, brightness_percentage: int):
"""Update icon based on brightness level."""
self.icon.set_from_icon_name(
"display-brightness-high-symbolic"
if brightness_percentage >= 80
else "display-brightness-low-symbolic"
if brightness_percentage < 50
else "display-brightness-medium-symbolic",
26,
)
def _update_brightness(self):
"""Update brightness when user drags the slider."""
if self.is_hovered():
new_brightness = int((self.scale.value / 100) * self.brightness.max_screen)
self.brightness.screen_brightness = new_brightness
self._last_brightness = int(self.scale.value)
self._update_icon(int(self.scale.value))
def update(self, *_):
"""Override to update display before showing OSD."""
# Update the display before showing
if self.brightness.screen_brightness is not None:
brightness_percentage = int(
(self.brightness.screen_brightness / self.brightness.max_screen) * 100
)
self._last_brightness = brightness_percentage
self.scale.animate_value(brightness_percentage)
self._update_icon(brightness_percentage)
# Call parent's update to show the OSD
super().update()