mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
feat: power cap frame in blp
This commit is contained in:
@@ -2,9 +2,11 @@ mod clocks_frame;
|
|||||||
mod gpu_stats_section;
|
mod gpu_stats_section;
|
||||||
mod oc_adjustment;
|
mod oc_adjustment;
|
||||||
mod performance_frame;
|
mod performance_frame;
|
||||||
mod power_cap_frame;
|
mod power_cap_section;
|
||||||
|
// mod power_cap_frame;
|
||||||
mod power_states;
|
mod power_states;
|
||||||
|
|
||||||
|
use self::power_cap_section::PowerCapSection;
|
||||||
use self::power_states::power_states_frame::PowerStatesFrame;
|
use self::power_states::power_states_frame::PowerStatesFrame;
|
||||||
use clocks_frame::ClocksFrame;
|
use clocks_frame::ClocksFrame;
|
||||||
use gpu_stats_section::GpuStatsSection;
|
use gpu_stats_section::GpuStatsSection;
|
||||||
@@ -16,7 +18,7 @@ use lact_client::schema::{
|
|||||||
DeviceStats, SystemInfo,
|
DeviceStats, SystemInfo,
|
||||||
};
|
};
|
||||||
use performance_frame::PerformanceFrame;
|
use performance_frame::PerformanceFrame;
|
||||||
use power_cap_frame::PowerCapFrame;
|
// use power_cap_frame::PowerCapFrame;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
@@ -28,7 +30,8 @@ pub struct OcPage {
|
|||||||
pub container: ScrolledWindow,
|
pub container: ScrolledWindow,
|
||||||
stats_section: GpuStatsSection,
|
stats_section: GpuStatsSection,
|
||||||
pub performance_frame: PerformanceFrame,
|
pub performance_frame: PerformanceFrame,
|
||||||
power_cap_frame: PowerCapFrame,
|
// power_cap_frame: PowerCapFrame,
|
||||||
|
power_cap_section: PowerCapSection,
|
||||||
pub power_states_frame: PowerStatesFrame,
|
pub power_states_frame: PowerStatesFrame,
|
||||||
pub clocks_frame: ClocksFrame,
|
pub clocks_frame: ClocksFrame,
|
||||||
pub enable_overclocking_button: Option<Button>,
|
pub enable_overclocking_button: Option<Button>,
|
||||||
@@ -58,7 +61,7 @@ impl OcPage {
|
|||||||
let stats_section = GpuStatsSection::new();
|
let stats_section = GpuStatsSection::new();
|
||||||
vbox.append(&stats_section);
|
vbox.append(&stats_section);
|
||||||
|
|
||||||
let power_cap_frame = PowerCapFrame::new();
|
let power_cap_section = PowerCapSection::new();
|
||||||
let performance_level_frame = PerformanceFrame::new();
|
let performance_level_frame = PerformanceFrame::new();
|
||||||
let clocks_frame = ClocksFrame::new();
|
let clocks_frame = ClocksFrame::new();
|
||||||
let power_states_frame = PowerStatesFrame::new();
|
let power_states_frame = PowerStatesFrame::new();
|
||||||
@@ -70,7 +73,7 @@ impl OcPage {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
vbox.append(&power_cap_frame.container);
|
vbox.append(&power_cap_section);
|
||||||
vbox.append(&performance_level_frame.container);
|
vbox.append(&performance_level_frame.container);
|
||||||
vbox.append(&power_states_frame);
|
vbox.append(&power_states_frame);
|
||||||
vbox.append(&clocks_frame.container);
|
vbox.append(&clocks_frame.container);
|
||||||
@@ -82,7 +85,7 @@ impl OcPage {
|
|||||||
stats_section,
|
stats_section,
|
||||||
performance_frame: performance_level_frame,
|
performance_frame: performance_level_frame,
|
||||||
clocks_frame,
|
clocks_frame,
|
||||||
power_cap_frame,
|
power_cap_section,
|
||||||
enable_overclocking_button,
|
enable_overclocking_button,
|
||||||
power_states_frame,
|
power_states_frame,
|
||||||
}
|
}
|
||||||
@@ -92,11 +95,20 @@ impl OcPage {
|
|||||||
self.stats_section.set_stats(stats);
|
self.stats_section.set_stats(stats);
|
||||||
self.power_states_frame.set_stats(stats);
|
self.power_states_frame.set_stats(stats);
|
||||||
if initial {
|
if initial {
|
||||||
self.power_cap_frame.set_data(
|
self.power_cap_section
|
||||||
stats.power.cap_current,
|
.set_max_value(stats.power.cap_max.unwrap_or_default());
|
||||||
stats.power.cap_max,
|
self.power_cap_section
|
||||||
stats.power.cap_default,
|
.set_min_value(stats.power.cap_min.unwrap_or_default());
|
||||||
);
|
self.power_cap_section
|
||||||
|
.set_default_value(stats.power.cap_default.unwrap_or_default());
|
||||||
|
|
||||||
|
if let Some(current_cap) = stats.power.cap_current {
|
||||||
|
self.power_cap_section.set_initial_value(current_cap);
|
||||||
|
self.power_cap_section.set_visible(true);
|
||||||
|
} else {
|
||||||
|
self.power_cap_section.set_visible(false);
|
||||||
|
}
|
||||||
|
|
||||||
self.set_performance_level(stats.performance_level);
|
self.set_performance_level(stats.performance_level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +132,8 @@ impl OcPage {
|
|||||||
|
|
||||||
pub fn connect_settings_changed<F: Fn() + 'static + Clone>(&self, f: F) {
|
pub fn connect_settings_changed<F: Fn() + 'static + Clone>(&self, f: F) {
|
||||||
self.performance_frame.connect_settings_changed(f.clone());
|
self.performance_frame.connect_settings_changed(f.clone());
|
||||||
self.power_cap_frame.connect_cap_changed(f.clone());
|
self.power_cap_section
|
||||||
|
.connect_current_value_notify(clone!(@strong f => move |_| f()));
|
||||||
self.clocks_frame.connect_clocks_changed(f.clone());
|
self.clocks_frame.connect_clocks_changed(f.clone());
|
||||||
self.power_states_frame.connect_values_changed(f);
|
self.power_states_frame.connect_values_changed(f);
|
||||||
}
|
}
|
||||||
@@ -145,7 +158,7 @@ impl OcPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_power_cap(&self) -> Option<f64> {
|
pub fn get_power_cap(&self) -> Option<f64> {
|
||||||
self.power_cap_frame.get_cap()
|
self.power_cap_section.get_user_cap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_enabled_power_states(&self) -> HashMap<PowerLevelKind, Vec<u8>> {
|
pub fn get_enabled_power_states(&self) -> HashMap<PowerLevelKind, Vec<u8>> {
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
use super::oc_adjustment::OcAdjustment;
|
|
||||||
use crate::app::page_section::PageSection;
|
|
||||||
use gtk::*;
|
|
||||||
use gtk::{glib::clone, prelude::*};
|
|
||||||
use std::{cell::Cell, rc::Rc};
|
|
||||||
use tracing::error;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct PowerCapFrame {
|
|
||||||
pub container: PageSection,
|
|
||||||
default_cap: Rc<Cell<Option<f64>>>,
|
|
||||||
adjustment: OcAdjustment,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PowerCapFrame {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
let container = PageSection::new("Power Usage Limit");
|
|
||||||
let default_cap = Rc::new(Cell::new(None));
|
|
||||||
|
|
||||||
let value_suffix = "W";
|
|
||||||
let root_box = Box::new(Orientation::Horizontal, 0);
|
|
||||||
|
|
||||||
let label = Label::new(None);
|
|
||||||
root_box.append(&label);
|
|
||||||
|
|
||||||
let adjustment = OcAdjustment::new(0.0, 0.0, 0.0, 1.0, 10.0, 0.0);
|
|
||||||
|
|
||||||
adjustment.connect_value_changed(clone!(@strong label => move |adj| {
|
|
||||||
let text = format!("{}/{} {}", adj.value().round(), adj.upper(), value_suffix);
|
|
||||||
label.set_label(&text);
|
|
||||||
}));
|
|
||||||
|
|
||||||
let scale = Scale::builder()
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.adjustment(&adjustment)
|
|
||||||
.hexpand(true)
|
|
||||||
.round_digits(0)
|
|
||||||
.margin_start(5)
|
|
||||||
.margin_end(5)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
scale.set_draw_value(false);
|
|
||||||
|
|
||||||
root_box.append(&scale);
|
|
||||||
|
|
||||||
let reset_button = Button::with_label("Default");
|
|
||||||
reset_button.connect_clicked(clone!(@strong adjustment, @strong default_cap => move |_| {
|
|
||||||
if let Some(cap) = default_cap.get() {
|
|
||||||
adjustment.set_value(cap);
|
|
||||||
} else {
|
|
||||||
error!("Could not set default cap, value not provided");
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
root_box.append(&reset_button);
|
|
||||||
|
|
||||||
container.append(&root_box);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
container,
|
|
||||||
adjustment,
|
|
||||||
default_cap,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_data(
|
|
||||||
&self,
|
|
||||||
power_cap: Option<f64>,
|
|
||||||
power_cap_max: Option<f64>,
|
|
||||||
power_cap_default: Option<f64>,
|
|
||||||
) {
|
|
||||||
if let (Some(power_cap_max), Some(power_cap)) = (power_cap_max, power_cap) {
|
|
||||||
self.adjustment.set_upper(power_cap_max);
|
|
||||||
self.adjustment.set_initial_value(power_cap);
|
|
||||||
self.container.set_visible(true);
|
|
||||||
} else {
|
|
||||||
self.container.set_visible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.default_cap.set(power_cap_default);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_cap(&self) -> Option<f64> {
|
|
||||||
self.adjustment.get_changed_value(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn connect_cap_changed<F: Fn() + 'static>(&self, f: F) {
|
|
||||||
self.adjustment.connect_value_changed(move |_| {
|
|
||||||
f();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
102
lact-gui/src/app/root_stack/oc_page/power_cap_section.rs
Normal file
102
lact-gui/src/app/root_stack/oc_page/power_cap_section.rs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
use crate::app::page_section::PageSection;
|
||||||
|
use gtk::glib::{self, subclass::types::ObjectSubclassIsExt, Object};
|
||||||
|
|
||||||
|
glib::wrapper! {
|
||||||
|
pub struct PowerCapSection(ObjectSubclass<imp::PowerCapSection>)
|
||||||
|
@extends PageSection, gtk::Box, gtk::Widget,
|
||||||
|
@implements gtk::Orientable, gtk::Accessible, gtk::Buildable;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PowerCapSection {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Object::builder().build()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_user_cap(&self) -> Option<f64> {
|
||||||
|
let imp = self.imp();
|
||||||
|
imp.adjustment.get_changed_value(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_initial_value(&self, value: f64) {
|
||||||
|
self.imp().adjustment.set_initial_value(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PowerCapSection {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod imp {
|
||||||
|
use crate::app::{page_section::PageSection, root_stack::oc_page::oc_adjustment::OcAdjustment};
|
||||||
|
use gtk::{
|
||||||
|
glib::{self, clone, subclass::InitializingObject, Properties, StaticTypeExt},
|
||||||
|
prelude::{ButtonExt, ObjectExt},
|
||||||
|
subclass::{
|
||||||
|
prelude::*,
|
||||||
|
widget::{CompositeTemplateClass, WidgetImpl},
|
||||||
|
},
|
||||||
|
Button, CompositeTemplate,
|
||||||
|
};
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
|
#[derive(CompositeTemplate, Default, Properties)]
|
||||||
|
#[properties(wrapper_type = super::PowerCapSection)]
|
||||||
|
#[template(file = "ui/oc_page/power_cap_section.blp")]
|
||||||
|
pub struct PowerCapSection {
|
||||||
|
#[property(get, set)]
|
||||||
|
pub current_value: RefCell<f64>,
|
||||||
|
#[property(get, set)]
|
||||||
|
pub max_value: RefCell<f64>,
|
||||||
|
#[property(get, set)]
|
||||||
|
pub min_value: RefCell<f64>,
|
||||||
|
#[property(get, set)]
|
||||||
|
pub default_value: RefCell<f64>,
|
||||||
|
#[property(get, set)]
|
||||||
|
pub value_text: RefCell<String>,
|
||||||
|
|
||||||
|
#[template_child]
|
||||||
|
pub adjustment: TemplateChild<OcAdjustment>,
|
||||||
|
#[template_child]
|
||||||
|
pub reset_button: TemplateChild<Button>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[glib::object_subclass]
|
||||||
|
impl ObjectSubclass for PowerCapSection {
|
||||||
|
const NAME: &'static str = "PowerCapSection";
|
||||||
|
type Type = super::PowerCapSection;
|
||||||
|
type ParentType = PageSection;
|
||||||
|
|
||||||
|
fn class_init(class: &mut Self::Class) {
|
||||||
|
OcAdjustment::ensure_type();
|
||||||
|
class.bind_template();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn instance_init(obj: &InitializingObject<Self>) {
|
||||||
|
obj.init_template();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[glib::derived_properties]
|
||||||
|
impl ObjectImpl for PowerCapSection {
|
||||||
|
fn constructed(&self) {
|
||||||
|
self.parent_constructed();
|
||||||
|
|
||||||
|
let obj = self.obj();
|
||||||
|
|
||||||
|
obj.connect_current_value_notify(clone!(@strong obj => move |section| {
|
||||||
|
let text = format!("{}/{} W", section.current_value(), section.max_value());
|
||||||
|
section.set_value_text(text);
|
||||||
|
}));
|
||||||
|
|
||||||
|
self.reset_button
|
||||||
|
.connect_clicked(clone!(@strong obj => move |_| {
|
||||||
|
obj.set_current_value(obj.default_value());
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WidgetImpl for PowerCapSection {}
|
||||||
|
impl BoxImpl for PowerCapSection {}
|
||||||
|
}
|
||||||
@@ -67,7 +67,7 @@ template $GpuStatsSection: $PageSection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$InfoRow {
|
$InfoRow {
|
||||||
name: "GPU Usage:";
|
name: "Power Usage:";
|
||||||
value: bind template.power-usage;
|
value: bind template.power-usage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
33
lact-gui/ui/oc_page/power_cap_section.blp
Normal file
33
lact-gui/ui/oc_page/power_cap_section.blp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using Gtk 4.0;
|
||||||
|
|
||||||
|
template $PowerCapSection: $PageSection {
|
||||||
|
name: "Power usage limit";
|
||||||
|
|
||||||
|
Box {
|
||||||
|
orientation: horizontal;
|
||||||
|
|
||||||
|
Label value_label {
|
||||||
|
label: bind template.value-text;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scale {
|
||||||
|
orientation: horizontal;
|
||||||
|
hexpand: true;
|
||||||
|
round-digits: 0;
|
||||||
|
margin-start: 5;
|
||||||
|
margin-end: 5;
|
||||||
|
draw-value: false;
|
||||||
|
adjustment: adjustment;
|
||||||
|
}
|
||||||
|
|
||||||
|
Button reset_button {
|
||||||
|
label: "Default";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$OcAdjustment adjustment {
|
||||||
|
value: bind template.current-value bidirectional;
|
||||||
|
lower: bind template.min-value;
|
||||||
|
upper: bind template.max-value;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user