mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
feat: update ui
This commit is contained in:
parent
90a4b504ef
commit
da0c08a532
@ -8,13 +8,16 @@ use adjustment_row::{ClockAdjustmentRow, ClockAdjustmentRowMsg, ClocksData};
|
|||||||
use amdgpu_sysfs::gpu_handle::overdrive::{ClocksTable as _, ClocksTableGen as AmdClocksTable};
|
use amdgpu_sysfs::gpu_handle::overdrive::{ClocksTable as _, ClocksTableGen as AmdClocksTable};
|
||||||
use gtk::{
|
use gtk::{
|
||||||
pango,
|
pango,
|
||||||
prelude::{BoxExt, ButtonExt, OrientableExt, WidgetExt},
|
prelude::{BoxExt, ButtonExt, CheckButtonExt, OrientableExt, WidgetExt},
|
||||||
};
|
};
|
||||||
use lact_schema::{
|
use lact_schema::{
|
||||||
request::{ClockspeedType, SetClocksCommand},
|
request::{ClockspeedType, SetClocksCommand},
|
||||||
ClocksTable, IntelClocksTable, NvidiaClockOffset, NvidiaClocksTable,
|
ClocksTable, IntelClocksTable, NvidiaClockOffset, NvidiaClocksTable,
|
||||||
};
|
};
|
||||||
use relm4::{factory::FactoryHashMap, ComponentParts, ComponentSender, RelmWidgetExt};
|
use relm4::{
|
||||||
|
binding::BoolBinding, factory::FactoryHashMap, ComponentParts, ComponentSender, RelmObjectExt,
|
||||||
|
RelmWidgetExt,
|
||||||
|
};
|
||||||
|
|
||||||
// This is only used on RDNA1 in practice
|
// This is only used on RDNA1 in practice
|
||||||
const DEFAULT_VOLTAGE_OFFSET_RANGE: i32 = 250;
|
const DEFAULT_VOLTAGE_OFFSET_RANGE: i32 = 250;
|
||||||
@ -23,12 +26,15 @@ const WARNING_TEXT: &str = "Warning: changing these values may lead to system in
|
|||||||
pub struct ClocksFrame {
|
pub struct ClocksFrame {
|
||||||
clocks: FactoryHashMap<ClockspeedType, ClockAdjustmentRow>,
|
clocks: FactoryHashMap<ClockspeedType, ClockAdjustmentRow>,
|
||||||
vram_clock_ratio: f64,
|
vram_clock_ratio: f64,
|
||||||
|
show_nvidia_pstate_info: bool,
|
||||||
|
show_all_pstates: BoolBinding,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ClocksFrameMsg {
|
pub enum ClocksFrameMsg {
|
||||||
Clocks(Option<ClocksTable>),
|
Clocks(Option<ClocksTable>),
|
||||||
VramRatio(f64),
|
VramRatio(f64),
|
||||||
|
TogglePStatesVisibility,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
@ -43,12 +49,36 @@ impl relm4::SimpleComponent for ClocksFrame {
|
|||||||
set_label: WARNING_TEXT,
|
set_label: WARNING_TEXT,
|
||||||
set_wrap_mode: pango::WrapMode::Word,
|
set_wrap_mode: pango::WrapMode::Word,
|
||||||
set_halign: gtk::Align::Start,
|
set_halign: gtk::Align::Start,
|
||||||
set_margin_vertical: 5,
|
set_margin_horizontal: 5,
|
||||||
|
},
|
||||||
|
|
||||||
|
append = >k::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_spacing: 5,
|
||||||
|
|
||||||
|
#[watch]
|
||||||
|
set_visible: model.show_nvidia_pstate_info,
|
||||||
|
|
||||||
|
append = >k::CheckButton {
|
||||||
|
set_label: Some("Show all P-States"),
|
||||||
|
add_binding["active"]: &model.show_all_pstates,
|
||||||
|
},
|
||||||
|
|
||||||
|
append = >k::Label {
|
||||||
|
add_binding["visible"]: &model.show_all_pstates,
|
||||||
|
|
||||||
|
set_margin_horizontal: 5,
|
||||||
|
set_markup: "<b>The following values are clock offsets for each P-State, going from highest to lowest.</b>",
|
||||||
|
set_wrap_mode: pango::WrapMode::Word,
|
||||||
|
set_halign: gtk::Align::Start,
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
append = model.clocks.widget() {
|
append = model.clocks.widget() {
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
set_spacing: 5,
|
set_spacing: 5,
|
||||||
|
set_margin_horizontal: 5,
|
||||||
},
|
},
|
||||||
|
|
||||||
append = >k::Label {
|
append = >k::Label {
|
||||||
@ -62,7 +92,7 @@ impl relm4::SimpleComponent for ClocksFrame {
|
|||||||
append = >k::Button {
|
append = >k::Button {
|
||||||
set_label: "Reset",
|
set_label: "Reset",
|
||||||
set_halign: gtk::Align::End,
|
set_halign: gtk::Align::End,
|
||||||
set_width_request: 75,
|
set_margin_horizontal: 5,
|
||||||
set_tooltip_text: Some("Warning: this resets all clock settings to defaults!"),
|
set_tooltip_text: Some("Warning: this resets all clock settings to defaults!"),
|
||||||
set_css_classes: &["destructive-action"],
|
set_css_classes: &["destructive-action"],
|
||||||
#[watch]
|
#[watch]
|
||||||
@ -78,15 +108,21 @@ impl relm4::SimpleComponent for ClocksFrame {
|
|||||||
fn init(
|
fn init(
|
||||||
_init: Self::Init,
|
_init: Self::Init,
|
||||||
root: Self::Root,
|
root: Self::Root,
|
||||||
_sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
let clocks = FactoryHashMap::builder().launch_default().detach();
|
let clocks = FactoryHashMap::builder().launch_default().detach();
|
||||||
|
|
||||||
let model = Self {
|
let model = Self {
|
||||||
clocks,
|
clocks,
|
||||||
vram_clock_ratio: 1.0,
|
vram_clock_ratio: 1.0,
|
||||||
|
show_nvidia_pstate_info: false,
|
||||||
|
show_all_pstates: BoolBinding::new(false),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
model
|
||||||
|
.show_all_pstates
|
||||||
|
.connect_value_notify(move |_| sender.input(ClocksFrameMsg::TogglePStatesVisibility));
|
||||||
|
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
|
||||||
ComponentParts { model, widgets }
|
ComponentParts { model, widgets }
|
||||||
@ -96,6 +132,8 @@ impl relm4::SimpleComponent for ClocksFrame {
|
|||||||
match msg {
|
match msg {
|
||||||
ClocksFrameMsg::Clocks(clocks_table) => {
|
ClocksFrameMsg::Clocks(clocks_table) => {
|
||||||
self.clocks.clear();
|
self.clocks.clear();
|
||||||
|
self.show_nvidia_pstate_info = false;
|
||||||
|
self.show_all_pstates.set_value(false);
|
||||||
|
|
||||||
if let Some(table) = clocks_table {
|
if let Some(table) = clocks_table {
|
||||||
match table {
|
match table {
|
||||||
@ -104,10 +142,31 @@ impl relm4::SimpleComponent for ClocksFrame {
|
|||||||
ClocksTable::Intel(table) => self.set_intel_table(table),
|
ClocksTable::Intel(table) => self.set_intel_table(table),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the width of all the labels is the same
|
||||||
|
let label_size_group = gtk::SizeGroup::new(gtk::SizeGroupMode::Horizontal);
|
||||||
|
let input_size_group = gtk::SizeGroup::new(gtk::SizeGroupMode::Horizontal);
|
||||||
|
|
||||||
|
for clockspeed_type in self.clocks.keys() {
|
||||||
|
self.clocks.send(
|
||||||
|
clockspeed_type,
|
||||||
|
ClockAdjustmentRowMsg::AddSizeGroup {
|
||||||
|
label_group: label_size_group.clone(),
|
||||||
|
input_group: input_size_group.clone(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ClocksFrameMsg::VramRatio(vram_ratio) => {
|
ClocksFrameMsg::VramRatio(vram_ratio) => {
|
||||||
self.vram_clock_ratio = vram_ratio;
|
self.vram_clock_ratio = vram_ratio;
|
||||||
}
|
}
|
||||||
|
ClocksFrameMsg::TogglePStatesVisibility => {
|
||||||
|
let show = self.show_all_pstates.value();
|
||||||
|
for key in self.clocks.keys() {
|
||||||
|
self.clocks
|
||||||
|
.send(key, ClockAdjustmentRowMsg::ShowSecondaryPStates(show));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.update_vram_clock_ratio();
|
self.update_vram_clock_ratio();
|
||||||
}
|
}
|
||||||
@ -190,6 +249,8 @@ impl ClocksFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_nvidia_table(&mut self, table: NvidiaClocksTable) {
|
fn set_nvidia_table(&mut self, table: NvidiaClocksTable) {
|
||||||
|
self.show_nvidia_pstate_info = true;
|
||||||
|
|
||||||
for (pstate, offset) in table.gpu_offsets {
|
for (pstate, offset) in table.gpu_offsets {
|
||||||
self.clocks.insert(
|
self.clocks.insert(
|
||||||
ClockspeedType::GpuClockOffset(pstate),
|
ClockspeedType::GpuClockOffset(pstate),
|
||||||
|
@ -25,6 +25,11 @@ pub struct ClocksData {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ClockAdjustmentRowMsg {
|
pub enum ClockAdjustmentRowMsg {
|
||||||
ValueRatio(f64),
|
ValueRatio(f64),
|
||||||
|
ShowSecondaryPStates(bool),
|
||||||
|
AddSizeGroup {
|
||||||
|
label_group: gtk::SizeGroup,
|
||||||
|
input_group: gtk::SizeGroup,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::factory(pub)]
|
#[relm4::factory(pub)]
|
||||||
@ -37,11 +42,13 @@ impl FactoryComponent for ClockAdjustmentRow {
|
|||||||
type Index = ClockspeedType;
|
type Index = ClockspeedType;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
|
#[name = "root_box"]
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
|
#[name = "title_label"]
|
||||||
gtk::Label {
|
gtk::Label {
|
||||||
set_width_request: 185,
|
|
||||||
set_xalign: 0.0,
|
set_xalign: 0.0,
|
||||||
set_label: &match self.clock_type {
|
#[watch]
|
||||||
|
set_markup: &match self.clock_type {
|
||||||
ClockspeedType::MaxCoreClock => "Maximum GPU Clock (MHz)".to_owned(),
|
ClockspeedType::MaxCoreClock => "Maximum GPU Clock (MHz)".to_owned(),
|
||||||
ClockspeedType::MaxMemoryClock => "Maximum VRAM Clock (MHz)".to_owned(),
|
ClockspeedType::MaxMemoryClock => "Maximum VRAM Clock (MHz)".to_owned(),
|
||||||
ClockspeedType::MaxVoltage => "Maximum GPU voltage (mV)".to_owned(),
|
ClockspeedType::MaxVoltage => "Maximum GPU voltage (mV)".to_owned(),
|
||||||
@ -49,10 +56,10 @@ impl FactoryComponent for ClockAdjustmentRow {
|
|||||||
ClockspeedType::MinMemoryClock => "Minimum VRAM Clock (MHz)".to_owned(),
|
ClockspeedType::MinMemoryClock => "Minimum VRAM Clock (MHz)".to_owned(),
|
||||||
ClockspeedType::MinVoltage => "Minimum GPU voltage (mV)".to_owned(),
|
ClockspeedType::MinVoltage => "Minimum GPU voltage (mV)".to_owned(),
|
||||||
ClockspeedType::VoltageOffset => "GPU voltage offset (mV)".to_owned(),
|
ClockspeedType::VoltageOffset => "GPU voltage offset (mV)".to_owned(),
|
||||||
ClockspeedType::GpuClockOffset(pstate) => format!("GPU Clock offset at P-State {pstate} (MHz)"),
|
ClockspeedType::GpuClockOffset(pstate) => format!("GPU P-State {pstate} Clock Offset (MHz)"),
|
||||||
ClockspeedType::MemClockOffset(pstate) => format!("VRAM Clock offset at P-State {pstate} (MHz)"),
|
ClockspeedType::MemClockOffset(pstate) => format!("VRAM P-State {pstate} Clock Offset (MHz)"),
|
||||||
ClockspeedType::Reset => unreachable!(),
|
ClockspeedType::Reset => unreachable!(),
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
gtk::Scale {
|
gtk::Scale {
|
||||||
@ -65,9 +72,9 @@ impl FactoryComponent for ClockAdjustmentRow {
|
|||||||
set_margin_horizontal: 5,
|
set_margin_horizontal: 5,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[name = "input_button"]
|
||||||
gtk::SpinButton {
|
gtk::SpinButton {
|
||||||
set_adjustment: &self.adjustment,
|
set_adjustment: &self.adjustment,
|
||||||
set_width_request: 120,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,7 +105,12 @@ impl FactoryComponent for ClockAdjustmentRow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, msg: Self::Input, _sender: relm4::FactorySender<Self>) {
|
fn update_with_view(
|
||||||
|
&mut self,
|
||||||
|
widgets: &mut Self::Widgets,
|
||||||
|
msg: Self::Input,
|
||||||
|
sender: relm4::FactorySender<Self>,
|
||||||
|
) {
|
||||||
match msg {
|
match msg {
|
||||||
ClockAdjustmentRowMsg::ValueRatio(ratio) => {
|
ClockAdjustmentRowMsg::ValueRatio(ratio) => {
|
||||||
self.adjustment.block_signal(&self.change_signal);
|
self.adjustment.block_signal(&self.change_signal);
|
||||||
@ -115,7 +127,20 @@ impl FactoryComponent for ClockAdjustmentRow {
|
|||||||
|
|
||||||
self.adjustment.unblock_signal(&self.change_signal);
|
self.adjustment.unblock_signal(&self.change_signal);
|
||||||
}
|
}
|
||||||
|
ClockAdjustmentRowMsg::AddSizeGroup {
|
||||||
|
label_group,
|
||||||
|
input_group,
|
||||||
|
} => {
|
||||||
|
label_group.add_widget(&widgets.title_label);
|
||||||
|
input_group.add_widget(&widgets.input_button);
|
||||||
|
}
|
||||||
|
ClockAdjustmentRowMsg::ShowSecondaryPStates(show_secondary) => {
|
||||||
|
let show_current = show_secondary || !clock_type_is_secondary(&self.clock_type);
|
||||||
|
widgets.root_box.set_visible(show_current);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.update_view(widgets, sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,3 +151,11 @@ impl ClockAdjustmentRow {
|
|||||||
.map(|value| (value / self.value_ratio) as i32)
|
.map(|value| (value / self.value_ratio) as i32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clock_type_is_secondary(clock_type: &ClockspeedType) -> bool {
|
||||||
|
match clock_type {
|
||||||
|
ClockspeedType::GpuClockOffset(pstate) => *pstate > 0,
|
||||||
|
ClockspeedType::MemClockOffset(pstate) => *pstate > 0,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user