From d91c61d8069f372b5e8ca6bfeac40695513cb36b Mon Sep 17 00:00:00 2001 From: tr1x_em Date: Mon, 11 Aug 2025 18:57:04 +0530 Subject: [PATCH] Added Wifi Signal Strenght Indicators --- .../icons/applets/caffeine-cup-empty.svg | 13 --- .../icons/applets/caffeine-cup-full.svg | 13 --- config/assets/icons/applets/caffeine-off.svg | 99 +++++++++++++++++ config/assets/icons/applets/caffeine-on.svg | 103 ++++++++++++++++++ config/assets/icons/applets/flight-off.svg | 82 ++++++++++++++ config/assets/icons/applets/flight-on.svg | 86 +++++++++++++++ .../icons/applets/network-flightmode-off.svg | 12 -- .../icons/applets/network-flightmode-on.svg | 8 -- modules/controlcenter/main.py | 20 ++-- modules/controlcenter/wifi.py | 59 ++++++---- modules/panel/components/indicators.py | 7 +- styles/controlcenter.css | 13 +++ utils/functions.py | 46 ++++++++ 13 files changed, 483 insertions(+), 78 deletions(-) delete mode 100644 config/assets/icons/applets/caffeine-cup-empty.svg delete mode 100644 config/assets/icons/applets/caffeine-cup-full.svg create mode 100644 config/assets/icons/applets/caffeine-off.svg create mode 100644 config/assets/icons/applets/caffeine-on.svg create mode 100644 config/assets/icons/applets/flight-off.svg create mode 100644 config/assets/icons/applets/flight-on.svg delete mode 100644 config/assets/icons/applets/network-flightmode-off.svg delete mode 100644 config/assets/icons/applets/network-flightmode-on.svg diff --git a/config/assets/icons/applets/caffeine-cup-empty.svg b/config/assets/icons/applets/caffeine-cup-empty.svg deleted file mode 100644 index 6175212..0000000 --- a/config/assets/icons/applets/caffeine-cup-empty.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/config/assets/icons/applets/caffeine-cup-full.svg b/config/assets/icons/applets/caffeine-cup-full.svg deleted file mode 100644 index ea4a065..0000000 --- a/config/assets/icons/applets/caffeine-cup-full.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/config/assets/icons/applets/caffeine-off.svg b/config/assets/icons/applets/caffeine-off.svg new file mode 100644 index 0000000..4e136a0 --- /dev/null +++ b/config/assets/icons/applets/caffeine-off.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + diff --git a/config/assets/icons/applets/caffeine-on.svg b/config/assets/icons/applets/caffeine-on.svg new file mode 100644 index 0000000..bbb3c63 --- /dev/null +++ b/config/assets/icons/applets/caffeine-on.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + diff --git a/config/assets/icons/applets/flight-off.svg b/config/assets/icons/applets/flight-off.svg new file mode 100644 index 0000000..fe276ae --- /dev/null +++ b/config/assets/icons/applets/flight-off.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + diff --git a/config/assets/icons/applets/flight-on.svg b/config/assets/icons/applets/flight-on.svg new file mode 100644 index 0000000..3aa4edb --- /dev/null +++ b/config/assets/icons/applets/flight-on.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + diff --git a/config/assets/icons/applets/network-flightmode-off.svg b/config/assets/icons/applets/network-flightmode-off.svg deleted file mode 100644 index ac3e7ce..0000000 --- a/config/assets/icons/applets/network-flightmode-off.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - diff --git a/config/assets/icons/applets/network-flightmode-on.svg b/config/assets/icons/applets/network-flightmode-on.svg deleted file mode 100644 index 5202b89..0000000 --- a/config/assets/icons/applets/network-flightmode-on.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/modules/controlcenter/main.py b/modules/controlcenter/main.py index 60c60c9..a931f3a 100644 --- a/modules/controlcenter/main.py +++ b/modules/controlcenter/main.py @@ -264,11 +264,11 @@ class ModusControlCenter(Window): self.flight_icon = Svg( name="flight-icon", svg_file=get_relative_path( - "../../config/assets/icons/applets/network-flightmode-on.svg" + "../../config/assets/icons/applets/flight-on.svg" if self.flight_mode - else "../../config/assets/icons/applets/network-flightmode-off.svg" + else "../../config/assets/icons/applets/flight-off.svg" ), - size=24, + size=46, ) self.flight_widget = Button( @@ -293,11 +293,11 @@ class ModusControlCenter(Window): self.caffeine_icon = Svg( name="caffeine-icon", svg_file=get_relative_path( - "../../config/assets/icons/applets/caffeine-cup-full.svg" + "../../config/assets/icons/applets/caffeine-on.svg" if self.caffeine_mode - else "../../config/assets/icons/applets/caffeine-cup-empty.svg" + else "../../config/assets/icons/applets/caffeine-off.svg" ), - size=24, + size=46, ) self.caffeine_widget = Button( @@ -671,9 +671,9 @@ class ModusControlCenter(Window): # Update icon self.flight_icon.set_from_file( get_relative_path( - "../../config/assets/icons/applets/network-flightmode-on.svg" + "../../config/assets/icons/applets/flight-on.svg" if self.flight_mode - else "../../config/assets/icons/applets/network-flightmode-off.svg" + else "../../config/assets/icons/applets/flight-off.svg" ) ) @@ -703,9 +703,9 @@ class ModusControlCenter(Window): self.caffeine_icon.set_from_file( get_relative_path( - "../../config/assets/icons/applets/caffeine-cup-full.svg" + "../../config/assets/icons/applets/caffeine-on.svg" if self.caffeine_mode - else "../../config/assets/icons/applets/caffeine-cup-empty.svg" + else "../../config/assets/icons/applets/caffeine-off.svg" ) ) diff --git a/modules/controlcenter/wifi.py b/modules/controlcenter/wifi.py index bd5ccd6..1c54899 100644 --- a/modules/controlcenter/wifi.py +++ b/modules/controlcenter/wifi.py @@ -7,8 +7,11 @@ from fabric.widgets.image import Image from fabric.widgets.centerbox import CenterBox from fabric.widgets.button import Button from fabric.widgets.box import Box +from fabric.widgets.svg import Svg +from fabric.utils import get_relative_path from gi.repository import Gdk, GLib, Gtk from fabric.widgets.separator import Separator +from utils.functions import get_wifi_icon_for_strength, get_wifi_connecting_icon import gi import subprocess @@ -37,13 +40,24 @@ class WifiNetworkSlot(Box): "connected" if self.is_connected else "", ] - # Create connection status indicator using symbolic WiFi icon - self.dimage = Image( - icon_name="network-wireless-symbolic", - size=16, + # Create connection status indicator using dynamic WiFi icon based on signal strength + wifi_icon_path = get_wifi_icon_for_strength(self.strength) + self.dimage = Svg( + svg_file=wifi_icon_path, + size=28, name="device-icon", - style_classes=" ".join(self.styles), ) + self.wifi_icon_box = Box( + children=[self.dimage], + style_classes=["wifi-icon-box"], + ) + if self.is_connected: + self.wifi_icon_box.remove_style_class("wifi-icon-box") + self.wifi_icon_box.add_style_class("wifi-icon-box-connected") + + # Set initial style classes + if self.is_connected: + self.dimage.add_style_class("connected") self.network_label = Label( label=self.ssid, name="wifi-network-name", h_align="start", h_expand=True @@ -66,8 +80,8 @@ class WifiNetworkSlot(Box): orientation="h", spacing=8, ) - start_box.children = [self.dimage, self.network_label] - if self.lock_icon is not None: + start_box.children = [self.wifi_icon_box, self.network_label] + if self.lock_icon: start_box.children.append(self.lock_icon) # Create end section with lock icon if needed @@ -80,10 +94,6 @@ class WifiNetworkSlot(Box): ) ] - if self.lock_icon is not None: - self.children.append(self.lock_icon) - end_children = [] - # Emit initial change to update display self.on_changed() @@ -92,8 +102,9 @@ class WifiNetworkSlot(Box): is_currently_connected = self.access_point.is_active if is_currently_connected: - # Show disconnecting state - self.dimage.set_property("icon-name", "network-wireless-acquiring-symbolic") + # Show disconnecting state using connecting icon + connecting_icon = get_wifi_connecting_icon() + self.dimage.set_from_file(connecting_icon) self.dimage.add_style_class("disconnecting") # Disconnect from network @@ -108,9 +119,8 @@ class WifiNetworkSlot(Box): self._show_password_dialog() else: # Try to connect without password (for open networks) - self.dimage.set_property( - "icon-name", "network-wireless-acquiring-symbolic" - ) + connecting_icon = get_wifi_connecting_icon() + self.dimage.set_from_file(connecting_icon) self.dimage.add_style_class("connecting") def on_open_connection_result(success, message): @@ -141,14 +151,16 @@ class WifiNetworkSlot(Box): def _reset_disconnect_state(self): """Reset visual state after disconnect operation""" self.dimage.remove_style_class("disconnecting") - self.dimage.set_property("icon-name", "network-wireless-symbolic") + wifi_icon_path = get_wifi_icon_for_strength(self.strength) + self.dimage.set_from_file(wifi_icon_path) self.on_changed() return False # Remove timeout def _reset_connect_state(self): """Reset visual state after connect operation""" self.dimage.remove_style_class("connecting") - self.dimage.set_property("icon-name", "network-wireless-symbolic") + wifi_icon_path = get_wifi_icon_for_strength(self.strength) + self.dimage.set_from_file(wifi_icon_path) self.on_changed() return False # Remove timeout @@ -158,7 +170,11 @@ class WifiNetworkSlot(Box): self.styles = [ "connected" if self.is_connected else "", ] - self.dimage.set_property("style-classes", " ".join(self.styles)) + # Update style classes for SVG widget + if self.is_connected: + self.dimage.add_style_class("connected") + else: + self.dimage.remove_style_class("connected") return def _show_password_dialog(self): @@ -182,8 +198,9 @@ class WifiNetworkSlot(Box): def _on_password_connect(self, ssid, password): """Handle password dialog connect action""" if password.strip(): - # Show connecting state - self.dimage.set_property("icon-name", "network-wireless-acquiring-symbolic") + # Show connecting state using connecting icon + connecting_icon = get_wifi_connecting_icon() + self.dimage.set_from_file(connecting_icon) self.dimage.add_style_class("connecting") # Try to connect with password using callback diff --git a/modules/panel/components/indicators.py b/modules/panel/components/indicators.py index 78df61f..9b9880c 100644 --- a/modules/panel/components/indicators.py +++ b/modules/panel/components/indicators.py @@ -11,6 +11,7 @@ from modules.controlcenter.wifi import WifiConnections from services.battery import Battery from services.network import NetworkClient from utils.roam import modus_service +from utils.functions import get_wifi_icon_for_strength, get_wifi_connecting_icon from widgets.mousecapture import DropDownMouseCapture from widgets.wayland import WaylandWindow as Window @@ -286,10 +287,14 @@ class NetworkIndicator(Box): tooltip = "WiFi disabled" elif wifi.active_access_point: ap = wifi.active_access_point - icon_file = "wifi-clear.svg" + # Use dynamic WiFi icon based on signal strength + wifi_icon_path = get_wifi_icon_for_strength(ap.strength) + self.network_icon.set_from_file(wifi_icon_path) tooltip = f"Connected to {ap.ssid}" if ap.strength >= 0: tooltip += f" ({ap.strength}%)" + self.network_button.set_tooltip_text(tooltip) + return # Early return to avoid setting icon again else: icon_file = "wifi-off-clear.svg" tooltip = "WiFi disconnected" diff --git a/styles/controlcenter.css b/styles/controlcenter.css index 96d8843..3a1e302 100644 --- a/styles/controlcenter.css +++ b/styles/controlcenter.css @@ -916,3 +916,16 @@ font-weight: bold; color: #ffffff; } + +.wifi-icon-box { + background-color: #aaaaaa; + border-radius: 50%; + padding: 2px; + /* margin-right: 8px; */ +} +.wifi-icon-box-connected { + background-color: #007aff; + border-radius: 50%; + padding: 2px; + /* margin-right: 8px; */ +} diff --git a/utils/functions.py b/utils/functions.py index fc6ea3c..7fed89b 100644 --- a/utils/functions.py +++ b/utils/functions.py @@ -49,3 +49,49 @@ def read_json_file(file_path: str) -> Optional[List]: except json.JSONDecodeError as e: logger.error(f"Failed to read JSON file {file_path}: {e}") return None + + +def get_wifi_icon_for_strength(strength: int) -> str: + """ + Get the appropriate WiFi icon based on signal strength. + + Args: + strength: Signal strength from 0-100 + + Returns: + Absolute path to the appropriate WiFi icon + """ + # Get the current directory where this script is located + current_dir = os.path.dirname(os.path.abspath(__file__)) + # Get the project root (parent of utils directory) + project_root = os.path.dirname(current_dir) + + if strength >= 80: + icon_name = "network-wireless-100.svg" + elif strength >= 60: + icon_name = "network-wireless-80.svg" + elif strength >= 40: + icon_name = "network-wireless-60.svg" + elif strength >= 20: + icon_name = "network-wireless-40.svg" + elif strength > 0: + icon_name = "network-wireless-20.svg" + else: + icon_name = "network-wireless-0.svg" + + return os.path.join(project_root, "config", "assets", "icons", "wifi", icon_name) + + +def get_wifi_connecting_icon() -> str: + """ + Get the WiFi connecting icon path. + + Returns: + Absolute path to the WiFi connecting icon + """ + # Get the current directory where this script is located + current_dir = os.path.dirname(os.path.abspath(__file__)) + # Get the project root (parent of utils directory) + project_root = os.path.dirname(current_dir) + + return os.path.join(project_root, "config", "assets", "icons", "wifi", "wifi-connecting.svg")