Initial Commit

This commit is contained in:
Stephen Horvath
2025-03-18 13:50:03 +10:00
commit f75092f982
6 changed files with 463 additions and 0 deletions

4
README.md Normal file
View File

@@ -0,0 +1,4 @@
# Yet Another Framework Interface
YAFI is another GUI for the Framework Laptop Embedded Controller.
It is written in Python with a GTK3 theme, and uses the `CrOS_EC_Python` library to communicate with the EC.

73
leds.ui Normal file
View File

@@ -0,0 +1,73 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.94.1 -->
<interface>
<!-- interface-description The LEDs page for YAFI -->
<!-- interface-authors Steve-Tech -->
<requires lib="gtk" version="4.0"/>
<requires lib="libadwaita" version="1.2"/>
<object class="GtkBox" id="leds-root">
<property name="orientation">vertical</property>
<child>
<object class="GtkListBox">
<property name="margin-end">10</property>
<property name="margin-start">10</property>
<child>
<object class="AdwActionRow">
<property name="selectable">False</property>
<property name="title">LED Control</property>
</object>
</child>
<child>
<object class="AdwActionRow" id="led-pwr">
<property name="title">Power Button</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkScale" id="led-pwr-scale">
<property name="adjustment">
<object class="GtkAdjustment">
<property name="lower">1.0</property>
<property name="page-increment">3.0</property>
<property name="step-increment">1.0</property>
<property name="upper">3.0</property>
<property name="value">3.0</property>
</object>
</property>
<property name="hexpand">True</property>
<property name="round-digits">0</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="led-kbd">
<property name="title">Keyboard Backlight</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkScale" id="led-kbd-scale">
<property name="adjustment">
<object class="GtkAdjustment">
<property name="page-increment">16.0</property>
<property name="step-increment">1.0</property>
<property name="upper">255.0</property>
<property name="value">255.0</property>
</object>
</property>
<property name="hexpand">True</property>
<property name="round-digits">0</property>
</object>
</child>
</object>
</child>
</object>
</child>
<style>
<class name="boxed-list"/>
</style>
</object>
</child>
</object>
</interface>

99
thermals.ui Normal file
View File

@@ -0,0 +1,99 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.94.1 -->
<interface>
<!-- interface-description The Thermals page for YAFI -->
<!-- interface-authors Steve-Tech -->
<requires lib="gtk" version="4.0"/>
<requires lib="libadwaita" version="1.6"/>
<object class="GtkPaned" id="thermals-root">
<property name="end-child">
<object class="GtkListBox" id="temperatures">
<child>
<object class="AdwActionRow">
<property name="selectable">False</property>
<property name="title">Temperatures</property>
</object>
</child>
</object>
</property>
<property name="start-child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkListBox">
<property name="margin-end">10</property>
<property name="margin-start">10</property>
<child>
<object class="AdwActionRow">
<property name="selectable">False</property>
<property name="title">Fan Control</property>
</object>
</child>
<child>
<object class="AdwActionRow" id="fan-rpm">
<property name="title">Current Speed</property>
<style>
<class name="property"/>
</style>
</object>
</child>
<child>
<object class="AdwComboRow" id="fan-mode">
<property name="model">
<object class="GtkStringList">
<items>
<item>Auto</item>
<item>Percent</item>
<item>RPM</item>
</items>
</object>
</property>
<property name="title">Speed Set Mode</property>
</object>
</child>
<child>
<object class="AdwActionRow" id="fan-set-percent">
<property name="title">Fan Speed</property>
<property name="visible">False</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkScale" id="fan-percent-scale">
<property name="adjustment">
<object class="GtkAdjustment">
<property name="page-increment">10.0</property>
<property name="step-increment">1.0</property>
<property name="upper">100.0</property>
<property name="value">100.0</property>
</object>
</property>
<property name="hexpand">True</property>
<property name="round-digits">0</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwSpinRow" id="fan-set-rpm">
<property name="adjustment">
<object class="GtkAdjustment">
<property name="page-increment">1000.0</property>
<property name="step-increment">100.0</property>
<property name="upper">65535.0</property>
</object>
</property>
<property name="title">Fan RPM Target</property>
<property name="visible">False</property>
</object>
</child>
<style>
<class name="boxed-list"/>
</style>
</object>
</child>
</object>
</property>
</object>
</interface>

128
yafi.cmb Normal file
View File

@@ -0,0 +1,128 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
<cambalache-project version="0.94.0" target_tk="gtk-4.0">
<ui>
(1,None,"yafi.ui","yafi.ui","YAFI is another GUI for the Framework Laptop Embedded Controller.",None,"Steve-Tech",None,None,None,None),
(2,None,None,"thermals.ui","The Thermals page for YAFI",None,"Steve-Tech",None,None,None,None),
(3,None,None,"leds.ui","The LEDs page for YAFI",None,"Steve-Tech",None,None,None,None)
</ui>
<object>
(1,1,"AdwApplicationWindow","root",None,None,None,None,0,None,None),
(1,2,"AdwNavigationSplitView",None,1,None,None,None,0,None,None),
(1,6,"AdwNavigationPage",None,2,None,None,None,0,None,None),
(1,7,"AdwNavigationPage",None,2,None,None,None,1,None,None),
(1,10,"AdwHeaderBar",None,11,None,"top",None,0,None,None),
(1,11,"AdwToolbarView",None,7,None,None,None,0,None,None),
(1,13,"AdwToolbarView",None,6,None,None,None,0,None,None),
(1,14,"AdwHeaderBar",None,13,None,"top",None,0,None,None),
(1,16,"GtkScrolledWindow",None,13,None,None,None,1,None,None),
(1,17,"GtkListBox","navbar",16,None,None,None,0,None,None),
(1,52,"GtkBox","content",53,None,None,None,0,None,None),
(1,53,"GtkScrolledWindow",None,11,None,None,None,1,None,None),
(2,2,"GtkPaned","thermals-root",None,None,None,None,1,None,None),
(2,3,"GtkListBox","temperatures",2,None,None,None,0,None,None),
(2,4,"AdwActionRow",None,3,None,None,None,0,None,None),
(2,5,"GtkBox",None,2,None,None,None,1,None,None),
(2,6,"GtkListBox",None,5,None,None,None,0,None,None),
(2,7,"AdwActionRow",None,6,None,None,None,0,None,None),
(2,8,"AdwActionRow","fan-rpm",6,None,None,None,1,None,None),
(2,9,"AdwComboRow","fan-mode",6,None,None,None,2,None,None),
(2,10,"GtkStringList",None,9,None,None,None,0,None,None),
(2,11,"AdwActionRow","fan-set-percent",6,None,None,None,3,None,None),
(2,12,"GtkBox",None,11,None,None,None,0,None,None),
(2,13,"GtkScale","fan-percent-scale",12,None,None,None,0,None,None),
(2,14,"GtkAdjustment",None,13,None,None,None,0,None,None),
(2,15,"AdwSpinRow","fan-set-rpm",6,None,None,None,4,None,None),
(2,16,"GtkAdjustment",None,15,None,None,None,0,None,None),
(3,4,"GtkBox","leds-root",None,None,None,None,1,None,None),
(3,5,"GtkListBox",None,4,None,None,None,0,None,None),
(3,6,"AdwActionRow",None,5,None,None,None,0,None,None),
(3,10,"AdwActionRow","led-pwr",5,None,None,None,1,None,None),
(3,11,"GtkBox",None,10,None,None,None,0,None,None),
(3,12,"GtkScale","led-pwr-scale",11,None,None,None,0,None,None),
(3,13,"GtkAdjustment",None,12,None,None,None,0,None,None),
(3,14,"AdwActionRow","led-kbd",5,None,None,None,2,None,None),
(3,15,"GtkBox",None,14,None,None,None,0,None,None),
(3,16,"GtkScale","led-kbd-scale",15,None,None,None,0,None,None),
(3,17,"GtkAdjustment",None,16,None,None,None,0,None,None)
</object>
<object_property>
(1,1,"GtkWindow","default-height","400",None,None,None,None,None,None,None,None,None),
(1,1,"GtkWindow","default-width","800",None,None,None,None,None,None,None,None,None),
(1,2,"AdwNavigationSplitView","content",None,None,None,None,None,7,None,None,None,None),
(1,2,"AdwNavigationSplitView","sidebar",None,None,None,None,None,6,None,None,None,None),
(1,6,"AdwNavigationPage","title","Settings",None,None,None,None,None,None,None,None,None),
(1,7,"AdwNavigationPage","title","Yet Another Framework Interface",None,None,None,None,None,None,None,None,None),
(1,52,"GtkBox","homogeneous","True",None,None,None,None,None,None,None,None,None),
(1,52,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
(2,2,"GtkPaned","end-child",None,0,None,None,None,3,None,None,None,None),
(2,2,"GtkPaned","start-child",None,0,None,None,None,5,None,None,None,None),
(2,4,"AdwPreferencesRow","title","Temperatures",0,None,None,None,None,None,None,None,None),
(2,4,"GtkListBoxRow","selectable","False",0,None,None,None,None,None,None,None,None),
(2,5,"GtkOrientable","orientation","vertical",0,None,None,None,None,None,None,None,None),
(2,6,"GtkWidget","margin-end","10",0,None,None,None,None,None,None,None,None),
(2,6,"GtkWidget","margin-start","10",0,None,None,None,None,None,None,None,None),
(2,7,"AdwPreferencesRow","title","Fan Control",0,None,None,None,None,None,None,None,None),
(2,7,"GtkListBoxRow","selectable","False",0,None,None,None,None,None,None,None,None),
(2,8,"AdwPreferencesRow","title","Current Speed",0,None,None,None,None,None,None,None,None),
(2,9,"AdwComboRow","model",None,0,None,None,None,10,None,None,None,None),
(2,9,"AdwPreferencesRow","title","Speed Set Mode",0,None,None,None,None,None,None,None,None),
(2,11,"AdwPreferencesRow","title","Fan Speed",0,None,None,None,None,None,None,None,None),
(2,11,"GtkWidget","visible","False",0,None,None,None,None,None,None,None,None),
(2,13,"GtkRange","adjustment",None,0,None,None,None,14,None,None,None,None),
(2,13,"GtkRange","round-digits","0",0,None,None,None,None,None,None,None,None),
(2,13,"GtkWidget","hexpand","True",0,None,None,None,None,None,None,None,None),
(2,14,"GtkAdjustment","page-increment","10.0",0,None,None,None,None,None,None,None,None),
(2,14,"GtkAdjustment","step-increment","1.0",0,None,None,None,None,None,None,None,None),
(2,14,"GtkAdjustment","upper","100.0",0,None,None,None,None,None,None,None,None),
(2,14,"GtkAdjustment","value","100.0",0,None,None,None,None,None,None,None,None),
(2,15,"AdwPreferencesRow","title","Fan RPM Target",0,None,None,None,None,None,None,None,None),
(2,15,"AdwSpinRow","adjustment",None,0,None,None,None,16,None,None,None,None),
(2,15,"GtkWidget","visible","False",0,None,None,None,None,None,None,None,None),
(2,16,"GtkAdjustment","page-increment","1000.0",0,None,None,None,None,None,None,None,None),
(2,16,"GtkAdjustment","step-increment","100.0",0,None,None,None,None,None,None,None,None),
(2,16,"GtkAdjustment","upper","65535.0",0,None,None,None,None,None,None,None,None),
(3,4,"GtkOrientable","orientation","vertical",0,None,None,None,None,None,None,None,None),
(3,5,"GtkWidget","margin-end","10",0,None,None,None,None,None,None,None,None),
(3,5,"GtkWidget","margin-start","10",0,None,None,None,None,None,None,None,None),
(3,6,"AdwPreferencesRow","title","LED Control",0,None,None,None,None,None,None,None,None),
(3,6,"GtkListBoxRow","selectable","False",0,None,None,None,None,None,None,None,None),
(3,10,"AdwPreferencesRow","title","Power Button",0,None,None,None,None,None,None,None,None),
(3,12,"GtkRange","adjustment",None,0,None,None,None,13,None,None,None,None),
(3,12,"GtkRange","round-digits","0",0,None,None,None,None,None,None,None,None),
(3,12,"GtkWidget","hexpand","True",0,None,None,None,None,None,None,None,None),
(3,13,"GtkAdjustment","lower","1.0",None,None,None,None,None,None,None,None,None),
(3,13,"GtkAdjustment","page-increment","3.0",0,None,None,None,None,None,None,None,None),
(3,13,"GtkAdjustment","step-increment","1.0",0,None,None,None,None,None,None,None,None),
(3,13,"GtkAdjustment","upper","3.0",0,None,None,None,None,None,None,None,None),
(3,13,"GtkAdjustment","value","3.0",0,None,None,None,None,None,None,None,None),
(3,14,"AdwPreferencesRow","title","Keyboard Backlight",0,None,None,None,None,None,None,None,None),
(3,16,"GtkRange","adjustment",None,0,None,None,None,17,None,None,None,None),
(3,16,"GtkRange","round-digits","0",0,None,None,None,None,None,None,None,None),
(3,16,"GtkWidget","hexpand","True",0,None,None,None,None,None,None,None,None),
(3,17,"GtkAdjustment","page-increment","16.0",0,None,None,None,None,None,None,None,None),
(3,17,"GtkAdjustment","step-increment","1.0",0,None,None,None,None,None,None,None,None),
(3,17,"GtkAdjustment","upper","255.0",0,None,None,None,None,None,None,None,None),
(3,17,"GtkAdjustment","value","255.0",0,None,None,None,None,None,None,None,None)
</object_property>
<object_data>
(1,17,"GtkWidget",1,1,None,None,None,None,None,None),
(1,17,"GtkWidget",2,2,None,1,None,None,None,None),
(2,8,"GtkWidget",1,1,None,None,None,None,None,None),
(2,8,"GtkWidget",2,2,None,1,None,None,None,None),
(2,10,"GtkStringList",1,1,None,None,None,None,None,None),
(2,10,"GtkStringList",2,2,"Auto",1,None,0,None,None),
(2,10,"GtkStringList",2,3,"Percent",1,None,0,None,None),
(2,10,"GtkStringList",2,4,"RPM",1,None,0,None,None),
(2,6,"GtkWidget",1,1,None,None,None,None,None,None),
(2,6,"GtkWidget",2,2,None,1,None,None,None,None),
(3,5,"GtkWidget",1,1,None,None,None,None,None,None),
(3,5,"GtkWidget",2,2,None,1,None,None,None,None)
</object_data>
<object_data_arg>
(1,17,"GtkWidget",2,2,"name","navigation-sidebar"),
(2,8,"GtkWidget",2,2,"name","property"),
(2,6,"GtkWidget",2,2,"name","boxed-list"),
(3,5,"GtkWidget",2,2,"name","boxed-list")
</object_data_arg>
</cambalache-project>

97
yafi.py Normal file
View File

@@ -0,0 +1,97 @@
import sys
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw
class YAFI(Adw.Application):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.connect('activate', self.on_activate)
def _change_page(self, builder, page):
content = builder.get_object("content")
while content_child := content.get_last_child():
content.remove(content_child)
content.append(page)
def _thermals_page(self, builder):
# Load the thermals.ui file
thermals_builder = Gtk.Builder()
thermals_builder.add_from_file("thermals.ui")
# Get the root widget from the thermals.ui file
thermals_root = thermals_builder.get_object("thermals-root")
self._change_page(builder, thermals_root)
fan_rpm = thermals_builder.get_object("fan-rpm")
fan_mode = thermals_builder.get_object("fan-mode")
fan_set_rpm = thermals_builder.get_object("fan-set-rpm")
fan_set_percent = thermals_builder.get_object("fan-set-percent")
fan_percent_scale = thermals_builder.get_object("fan-percent-scale")
def handle_fan_mode(mode):
match mode:
case 0: # Auto
fan_set_rpm.set_visible(False)
fan_set_percent.set_visible(False)
case 1: # Percent
fan_set_rpm.set_visible(False)
fan_set_percent.set_visible(True)
case 2: # RPM
fan_set_rpm.set_visible(True)
fan_set_percent.set_visible(False)
fan_rpm.set_subtitle("1200 RPM")
fan_mode.connect("notify::selected", lambda combo, _: handle_fan_mode(combo.get_selected()))
fan_percent_scale.connect(
"value-changed",
lambda scale: fan_set_percent.set_subtitle(f"{int(scale.get_value())} %"),
)
temperatures = thermals_builder.get_object("temperatures")
for i in ((25.0, "Sensor 1"), (30.0, "Sensor 2"), (35.0, "Sensor 3"), (40.0, "Sensor 4")):
new_row = Adw.ActionRow(title=i[1], subtitle=f"{i[0]}°C")
new_row.add_css_class("property")
temperatures.append(new_row)
def _leds_page(self, builder):
# Load the leds.ui file
leds_builder = Gtk.Builder()
leds_builder.add_from_file("leds.ui")
# Get the root widget from the leds.ui file
leds_root = leds_builder.get_object("leds-root")
self._change_page(builder, leds_root)
def on_activate(self, app):
# Create a Builder
builder = Gtk.Builder()
builder.add_from_file("yafi.ui")
self._thermals_page(builder)
pages = (("Thermals", self._thermals_page), ("LEDs", self._leds_page), ("Battery", self._leds_page), ("About", self._leds_page))
# Build the navbar
navbar = builder.get_object("navbar")
for page in pages:
row = Gtk.ListBoxRow()
row.set_child(Gtk.Label(label=page[0]))
navbar.append(row)
navbar.connect("row-activated", lambda box, row: pages[row.get_index()][1](builder))
# Obtain and show the main window
self.win = builder.get_object("root")
self.win.set_application(self)
self.win.present()
app = YAFI(application_id="au.stevetech.yafi")
app.run(sys.argv)

62
yafi.ui Normal file
View File

@@ -0,0 +1,62 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.94.1 -->
<interface>
<!-- interface-name yafi.ui -->
<!-- interface-description YAFI is another GUI for the Framework Laptop Embedded Controller. -->
<!-- interface-authors Steve-Tech -->
<requires lib="gtk" version="4.12"/>
<requires lib="libadwaita" version="1.4"/>
<object class="AdwApplicationWindow" id="root">
<property name="default-height">400</property>
<property name="default-width">800</property>
<child>
<object class="AdwNavigationSplitView">
<property name="content">
<object class="AdwNavigationPage">
<property name="title">Yet Another Framework Interface</property>
<child>
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar"/>
</child>
<child>
<object class="GtkScrolledWindow">
<child>
<object class="GtkBox" id="content">
<property name="homogeneous">True</property>
<property name="orientation">vertical</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
<property name="sidebar">
<object class="AdwNavigationPage">
<property name="title">Settings</property>
<child>
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar"/>
</child>
<child>
<object class="GtkScrolledWindow">
<child>
<object class="GtkListBox" id="navbar">
<style>
<class name="navigation-sidebar"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>
</object>
</interface>