mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2026-11-03 12:50:31 -06:00
refactor: adjustment-row on oc page (#1194)
* refactor: adjustment-row on oc page * change steps for adjustment rows
This commit is contained in:
1 parent
c83827d40b
commit
5f53c5bc29
11 files changed
+369
-298
No files matched your search
@@ -0,0 +1,215 @@
|
||||
use super::adjustment_value::AdjustmentValue;
|
||||
use crate::app::utils::ext::make_event_controller_no_scroll;
|
||||
use adw::prelude::*;
|
||||
use relm4::{FactorySender, RelmWidgetExt, css, factory::FactoryComponent};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub struct AdjustmentRow<Key> {
|
||||
title: String,
|
||||
title_tooltip: String,
|
||||
info_text: String,
|
||||
_key: PhantomData<Key>,
|
||||
adjustment: AdjustmentValue,
|
||||
value_ratio: f64,
|
||||
}
|
||||
|
||||
pub struct AdjustmentRowInit {
|
||||
pub title: String,
|
||||
pub title_tooltip: String,
|
||||
pub info_text: String,
|
||||
pub value: f64,
|
||||
pub lower: f64,
|
||||
pub upper: f64,
|
||||
pub step_increment: f64,
|
||||
pub page_increment: f64,
|
||||
}
|
||||
|
||||
impl Default for AdjustmentRowInit {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
title: String::new(),
|
||||
title_tooltip: String::new(),
|
||||
info_text: String::new(),
|
||||
value: 0.0,
|
||||
lower: 0.0,
|
||||
upper: 0.0,
|
||||
step_increment: 1.0,
|
||||
page_increment: 10.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AdjustmentRowMsg {
|
||||
/// Change display units and reset the edit state.
|
||||
ValueRatio(f64),
|
||||
/// Set a value as an edit, for example when the user presses Reset.
|
||||
SetValue(f64),
|
||||
SetVisible(bool),
|
||||
AddSizeGroup {
|
||||
label_group: gtk::SizeGroup,
|
||||
input_group: gtk::SizeGroup,
|
||||
},
|
||||
}
|
||||
|
||||
#[relm4::factory(pub)]
|
||||
impl<Key: 'static> FactoryComponent for AdjustmentRow<Key> {
|
||||
type ParentWidget = gtk::Box;
|
||||
type Index = Key;
|
||||
type Init = AdjustmentRowInit;
|
||||
type Input = AdjustmentRowMsg;
|
||||
// Both slider changes and uncommitted spin-button text edits notify the parent.
|
||||
type Output = ();
|
||||
type CommandOutput = ();
|
||||
|
||||
view! {
|
||||
#[root]
|
||||
#[name = "root_box"]
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
add_css_class: "adjustment-row",
|
||||
|
||||
#[name = "title_box"]
|
||||
gtk::Box {
|
||||
set_spacing: 5,
|
||||
|
||||
#[name = "label"]
|
||||
gtk::Label {
|
||||
set_xalign: 0.0,
|
||||
set_markup: &self.title,
|
||||
set_tooltip_text: (!self.title_tooltip.is_empty()).then_some(self.title_tooltip.as_str()),
|
||||
},
|
||||
|
||||
#[name = "info_button"]
|
||||
gtk::MenuButton {
|
||||
set_icon_name: "dialog-information-symbolic",
|
||||
set_always_show_arrow: false,
|
||||
add_css_class: css::FLAT,
|
||||
set_visible: !self.info_text.is_empty(),
|
||||
|
||||
#[wrap(Some)]
|
||||
set_popover = >k::Popover {
|
||||
#[name = "info_label"]
|
||||
gtk::Label {
|
||||
set_label: &self.info_text,
|
||||
set_margin_all: 5,
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
set_max_width_chars: 55,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
#[name = "scale"]
|
||||
gtk::Scale {
|
||||
set_adjustment: &self.adjustment,
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_hexpand: true,
|
||||
set_digits: 0,
|
||||
set_round_digits: 0,
|
||||
set_value_pos: gtk::PositionType::Right,
|
||||
set_width_request: 100,
|
||||
add_controller = make_event_controller_no_scroll(),
|
||||
},
|
||||
|
||||
#[name = "spinbutton"]
|
||||
gtk::SpinButton {
|
||||
set_adjustment: &self.adjustment,
|
||||
add_controller = make_event_controller_no_scroll(),
|
||||
connect_changed[sender] => move |_| {
|
||||
let _ = sender.output(());
|
||||
} @ text_change_signal,
|
||||
},
|
||||
},
|
||||
|
||||
#[local_ref]
|
||||
adjustment -> AdjustmentValue {
|
||||
connect_value_changed[sender] => move |_| {
|
||||
let _ = sender.output(());
|
||||
} @ value_change_signal,
|
||||
},
|
||||
}
|
||||
|
||||
fn init_model(init: Self::Init, _index: &Self::Index, _sender: FactorySender<Self>) -> Self {
|
||||
Self {
|
||||
title: init.title,
|
||||
title_tooltip: init.title_tooltip,
|
||||
info_text: init.info_text,
|
||||
_key: PhantomData,
|
||||
adjustment: AdjustmentValue::new(
|
||||
init.value,
|
||||
init.lower,
|
||||
init.upper,
|
||||
init.step_increment,
|
||||
init.page_increment,
|
||||
),
|
||||
value_ratio: 1.0,
|
||||
}
|
||||
}
|
||||
|
||||
fn init_widgets(
|
||||
&mut self,
|
||||
_index: &Self::Index,
|
||||
root: Self::Root,
|
||||
_returned_widget: >k::Widget,
|
||||
sender: FactorySender<Self>,
|
||||
) -> Self::Widgets {
|
||||
let adjustment = &self.adjustment;
|
||||
let widgets = view_output!();
|
||||
widgets
|
||||
}
|
||||
|
||||
fn update_with_view(
|
||||
&mut self,
|
||||
widgets: &mut Self::Widgets,
|
||||
msg: Self::Input,
|
||||
_sender: FactorySender<Self>,
|
||||
) {
|
||||
match msg {
|
||||
AdjustmentRowMsg::ValueRatio(ratio) => {
|
||||
// Changing display units must not emit an edit notification.
|
||||
self.adjustment.block_signal(&widgets.value_change_signal);
|
||||
widgets.spinbutton.block_signal(&widgets.text_change_signal);
|
||||
|
||||
let raw_current = self.adjustment.value() / self.value_ratio;
|
||||
let raw_min = self.adjustment.lower() / self.value_ratio;
|
||||
let raw_max = self.adjustment.upper() / self.value_ratio;
|
||||
|
||||
self.adjustment.set_lower(raw_min * ratio);
|
||||
self.adjustment.set_upper(raw_max * ratio);
|
||||
self.adjustment.set_initial_value(raw_current * ratio);
|
||||
|
||||
self.value_ratio = ratio;
|
||||
|
||||
widgets
|
||||
.spinbutton
|
||||
.unblock_signal(&widgets.text_change_signal);
|
||||
self.adjustment.unblock_signal(&widgets.value_change_signal);
|
||||
}
|
||||
AdjustmentRowMsg::SetValue(value) => {
|
||||
self.adjustment.set_value(value * self.value_ratio);
|
||||
}
|
||||
AdjustmentRowMsg::SetVisible(visible) => widgets.root_box.set_visible(visible),
|
||||
AdjustmentRowMsg::AddSizeGroup {
|
||||
label_group,
|
||||
input_group,
|
||||
} => {
|
||||
label_group.add_widget(&widgets.title_box);
|
||||
input_group.add_widget(&widgets.spinbutton);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Key> AdjustmentRow<Key> {
|
||||
pub fn get_value(&self) -> f64 {
|
||||
self.adjustment.value() / self.value_ratio
|
||||
}
|
||||
|
||||
pub fn get_changed_value(&self) -> Option<f64> {
|
||||
self.adjustment
|
||||
.get_changed_value(false)
|
||||
.map(|value| value / self.value_ratio)
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -4,20 +4,20 @@ use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OcAdjustment {
|
||||
pub struct AdjustmentValue {
|
||||
pub changed: Rc<AtomicBool>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for OcAdjustment {
|
||||
const NAME: &'static str = "OcAdjustment";
|
||||
type Type = super::OcAdjustment;
|
||||
impl ObjectSubclass for AdjustmentValue {
|
||||
const NAME: &'static str = "AdjustmentValue";
|
||||
type Type = super::AdjustmentValue;
|
||||
type ParentType = gtk::Adjustment;
|
||||
}
|
||||
|
||||
impl ObjectImpl for OcAdjustment {}
|
||||
impl ObjectImpl for AdjustmentValue {}
|
||||
|
||||
impl AdjustmentImpl for OcAdjustment {
|
||||
impl AdjustmentImpl for AdjustmentValue {
|
||||
fn value_changed(&self) {
|
||||
self.parent_value_changed();
|
||||
self.changed.store(true, Ordering::SeqCst);
|
||||
+7
-7
@@ -10,18 +10,18 @@ use std::sync::atomic::Ordering;
|
||||
use tracing::debug;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct OcAdjustment(ObjectSubclass<imp::OcAdjustment>)
|
||||
pub struct AdjustmentValue(ObjectSubclass<imp::AdjustmentValue>)
|
||||
@extends gtk::Adjustment,
|
||||
@implements gtk::Actionable, gtk::Buildable, gtk::ConstraintTarget;
|
||||
}
|
||||
|
||||
impl Default for OcAdjustment {
|
||||
impl Default for AdjustmentValue {
|
||||
fn default() -> Self {
|
||||
Object::builder().build()
|
||||
}
|
||||
}
|
||||
|
||||
impl OcAdjustment {
|
||||
impl AdjustmentValue {
|
||||
pub fn new(
|
||||
value: f64,
|
||||
lower: f64,
|
||||
@@ -29,18 +29,18 @@ impl OcAdjustment {
|
||||
step_increment: f64,
|
||||
page_increment: f64,
|
||||
) -> Self {
|
||||
let oc_adjustment = Self::default();
|
||||
let adjustment_value = Self::default();
|
||||
|
||||
let adjustment = oc_adjustment.imp().obj();
|
||||
let adjustment = adjustment_value.imp().obj();
|
||||
adjustment.set_lower(lower);
|
||||
adjustment.set_upper(upper);
|
||||
adjustment.set_step_increment(step_increment);
|
||||
adjustment.set_page_increment(page_increment);
|
||||
adjustment.set_page_size(0.0);
|
||||
|
||||
oc_adjustment.set_initial_value(value);
|
||||
adjustment_value.set_initial_value(value);
|
||||
|
||||
oc_adjustment
|
||||
adjustment_value
|
||||
}
|
||||
|
||||
pub fn get_changed_value(&self, filter_zero: bool) -> Option<f64> {
|
||||
@@ -1,7 +1,8 @@
|
||||
pub(crate) mod adjustment_row;
|
||||
pub(crate) mod adjustment_value;
|
||||
pub(crate) mod gpu_stats_section;
|
||||
pub(crate) mod info_row;
|
||||
pub(crate) mod info_row_level;
|
||||
pub(crate) mod loader;
|
||||
pub(crate) mod oc_adjustment;
|
||||
pub(crate) mod page_section;
|
||||
pub(crate) mod page_section_expander;
|
||||
@@ -4,4 +4,8 @@
|
||||
|
||||
.clocks-frame-group .card {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.clocks-frame-group .adjustment-row > scale {
|
||||
min-width: 100px;
|
||||
}
|
||||
@@ -1,7 +1,16 @@
|
||||
use super::adjustment_row::{ClockAdjustmentRow, ClockAdjustmentRowMsg, ClocksData};
|
||||
use gtk::prelude::{BoxExt, OrientableExt, WidgetExt};
|
||||
use super::{ClocksData, clock_title};
|
||||
use crate::{
|
||||
APP_BROKER, I18N,
|
||||
app::{
|
||||
components::adjustment_row::{AdjustmentRow, AdjustmentRowInit, AdjustmentRowMsg},
|
||||
msg::AppMsg,
|
||||
},
|
||||
};
|
||||
use adw::prelude::*;
|
||||
use i18n_embed_fl::fl;
|
||||
use lact_schema::request::ClockspeedType;
|
||||
use relm4::{css, factory::FactoryHashMap, prelude::FactoryComponent};
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum ClockCategory {
|
||||
@@ -58,7 +67,8 @@ impl ClockCategory {
|
||||
}
|
||||
|
||||
pub struct AdjustmentGroup {
|
||||
adjustments: FactoryHashMap<ClockspeedType, ClockAdjustmentRow>,
|
||||
adjustments: FactoryHashMap<ClockspeedType, AdjustmentRow<ClockspeedType>>,
|
||||
secondary_clocks: HashSet<ClockspeedType>,
|
||||
}
|
||||
|
||||
impl AdjustmentGroup {
|
||||
@@ -67,18 +77,38 @@ impl AdjustmentGroup {
|
||||
}
|
||||
|
||||
pub fn has_secondary(&self) -> bool {
|
||||
self.adjustments.values().any(|row| row.is_secondary)
|
||||
!self.secondary_clocks.is_empty()
|
||||
}
|
||||
|
||||
pub fn set_clock(&mut self, clock_type: ClockspeedType, data: ClocksData) {
|
||||
self.adjustments.insert(clock_type, data);
|
||||
self.adjustments.insert(
|
||||
clock_type,
|
||||
AdjustmentRowInit {
|
||||
title: data.custom_title.unwrap_or_else(|| clock_title(clock_type)),
|
||||
info_text: if clock_type == ClockspeedType::VoltageBoost {
|
||||
fl!(I18N, "gpu-voltage-boost-tooltip")
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
value: f64::from(data.current),
|
||||
lower: f64::from(data.min),
|
||||
upper: f64::from(data.max),
|
||||
step_increment: get_row_step(clock_type),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
if data.is_secondary {
|
||||
self.secondary_clocks.insert(clock_type);
|
||||
} else {
|
||||
self.secondary_clocks.remove(&clock_type);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_size_group(&self, label_group: gtk::SizeGroup, input_group: gtk::SizeGroup) {
|
||||
for clock_type in self.adjustments.keys() {
|
||||
self.adjustments.send(
|
||||
clock_type,
|
||||
ClockAdjustmentRowMsg::AddSizeGroup {
|
||||
AdjustmentRowMsg::AddSizeGroup {
|
||||
label_group: label_group.clone(),
|
||||
input_group: input_group.clone(),
|
||||
},
|
||||
@@ -89,7 +119,7 @@ impl AdjustmentGroup {
|
||||
pub fn set_value_ratio(&self, ratio: f64) {
|
||||
for clock_type in self.adjustments.keys() {
|
||||
self.adjustments
|
||||
.send(clock_type, ClockAdjustmentRowMsg::ValueRatio(ratio));
|
||||
.send(clock_type, AdjustmentRowMsg::ValueRatio(ratio));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +133,7 @@ impl AdjustmentGroup {
|
||||
) {
|
||||
let mut any_visible = false;
|
||||
|
||||
for (key, row) in self.adjustments.iter() {
|
||||
for key in self.adjustments.keys() {
|
||||
let show_current = match key {
|
||||
ClockspeedType::MaxCoreClock | ClockspeedType::MinCoreClock
|
||||
if show_nvidia_options =>
|
||||
@@ -118,13 +148,13 @@ impl AdjustmentGroup {
|
||||
ClockspeedType::GpuClockOffset(_) if show_nvidia_options && vf_curve_editing => {
|
||||
false
|
||||
}
|
||||
_ => !row.is_secondary || show_secondary,
|
||||
_ => !self.secondary_clocks.contains(key) || show_secondary,
|
||||
};
|
||||
|
||||
any_visible |= show_current;
|
||||
|
||||
self.adjustments
|
||||
.send(key, ClockAdjustmentRowMsg::SetVisible(show_current));
|
||||
.send(key, AdjustmentRowMsg::SetVisible(show_current));
|
||||
}
|
||||
|
||||
// removes empty card
|
||||
@@ -134,7 +164,12 @@ impl AdjustmentGroup {
|
||||
pub fn get_commands(&self) -> Vec<(ClockspeedType, Option<i32>)> {
|
||||
self.adjustments
|
||||
.iter()
|
||||
.map(|(clock_type, row)| (*clock_type, row.get_configured_value()))
|
||||
.map(|(clock_type, row)| {
|
||||
(
|
||||
*clock_type,
|
||||
row.get_changed_value().map(|value| value as i32),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -142,7 +177,7 @@ impl AdjustmentGroup {
|
||||
for clock_type in self.adjustments.keys() {
|
||||
if matches!(clock_type, ClockspeedType::GpuClockOffset(_)) {
|
||||
self.adjustments
|
||||
.send(clock_type, ClockAdjustmentRowMsg::SetValue(0));
|
||||
.send(clock_type, AdjustmentRowMsg::SetValue(0.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,11 +185,23 @@ impl AdjustmentGroup {
|
||||
pub fn get_raw_value(&self, clock_type: ClockspeedType) -> i32 {
|
||||
self.adjustments
|
||||
.get(&clock_type)
|
||||
.map(|row| row.get_raw_value())
|
||||
.map(|row| row.get_value() as i32)
|
||||
.unwrap_or(0)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_row_step(clock_type: ClockspeedType) -> f64 {
|
||||
match ClockCategory::from_type(clock_type) {
|
||||
ClockCategory::CoreClock
|
||||
| ClockCategory::VramClock
|
||||
| ClockCategory::CoreCurveClock
|
||||
| ClockCategory::VramCurveClock => 5.0,
|
||||
ClockCategory::CoreVoltage
|
||||
| ClockCategory::CoreCurveVoltage
|
||||
| ClockCategory::VramCurveVoltage => 1.0,
|
||||
}
|
||||
}
|
||||
|
||||
#[relm4::factory(pub)]
|
||||
impl FactoryComponent for AdjustmentGroup {
|
||||
type Init = ();
|
||||
@@ -175,7 +222,10 @@ impl FactoryComponent for AdjustmentGroup {
|
||||
|
||||
fn init_model(_: Self::Init, _: &Self::Index, _: relm4::FactorySender<Self>) -> Self {
|
||||
Self {
|
||||
adjustments: FactoryHashMap::builder().launch_default().detach(),
|
||||
adjustments: FactoryHashMap::builder()
|
||||
.launch_default()
|
||||
.forward(APP_BROKER.sender(), |()| AppMsg::SettingsChanged),
|
||||
secondary_clocks: HashSet::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,245 +0,0 @@
|
||||
use crate::{
|
||||
APP_BROKER, I18N,
|
||||
app::{
|
||||
components::oc_adjustment::OcAdjustment, msg::AppMsg,
|
||||
utils::ext::make_event_controller_no_scroll,
|
||||
},
|
||||
};
|
||||
use gtk::{
|
||||
glib::{SignalHandlerId, object::ObjectExt},
|
||||
prelude::{AdjustmentExt, BoxExt, EditableExt, OrientableExt, RangeExt, ScaleExt, WidgetExt},
|
||||
};
|
||||
use i18n_embed_fl::fl;
|
||||
use lact_schema::request::ClockspeedType;
|
||||
use relm4::{RelmWidgetExt, prelude::FactoryComponent};
|
||||
|
||||
pub struct ClockAdjustmentRow {
|
||||
clock_type: ClockspeedType,
|
||||
custom_title: Option<String>,
|
||||
value_ratio: f64,
|
||||
change_signal: SignalHandlerId,
|
||||
adjustment: OcAdjustment,
|
||||
pub(super) is_secondary: bool,
|
||||
}
|
||||
|
||||
pub struct ClocksData {
|
||||
pub current: i32,
|
||||
pub min: i32,
|
||||
pub max: i32,
|
||||
pub custom_title: Option<String>,
|
||||
pub is_secondary: bool,
|
||||
pub step: i32,
|
||||
}
|
||||
|
||||
impl Default for ClocksData {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
current: 0,
|
||||
min: 0,
|
||||
max: 0,
|
||||
custom_title: None,
|
||||
is_secondary: false,
|
||||
step: 10,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ClocksData {
|
||||
pub fn new(current: i32, min: i32, max: i32) -> Self {
|
||||
Self {
|
||||
current,
|
||||
min,
|
||||
max,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClockAdjustmentRowMsg {
|
||||
ValueRatio(f64),
|
||||
SetValue(i32),
|
||||
SetVisible(bool),
|
||||
AddSizeGroup {
|
||||
label_group: gtk::SizeGroup,
|
||||
input_group: gtk::SizeGroup,
|
||||
},
|
||||
}
|
||||
|
||||
#[relm4::factory(pub)]
|
||||
impl FactoryComponent for ClockAdjustmentRow {
|
||||
type ParentWidget = gtk::Box;
|
||||
type CommandOutput = ();
|
||||
type Init = ClocksData;
|
||||
type Input = ClockAdjustmentRowMsg;
|
||||
type Output = ();
|
||||
type Index = ClockspeedType;
|
||||
|
||||
view! {
|
||||
#[name = "root_box"]
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
|
||||
#[name = "title_box"]
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_spacing: 5,
|
||||
|
||||
gtk::Label {
|
||||
set_xalign: 0.0,
|
||||
#[watch]
|
||||
set_markup: &match &self.custom_title {
|
||||
Some(title) => title.clone(),
|
||||
None => {
|
||||
match self.clock_type {
|
||||
ClockspeedType::MaxCoreClock => fl!(I18N, "max-gpu-clock"),
|
||||
ClockspeedType::MaxMemoryClock => fl!(I18N, "max-vram-clock"),
|
||||
ClockspeedType::MaxVoltage => fl!(I18N, "max-gpu-voltage"),
|
||||
ClockspeedType::MinCoreClock => fl!(I18N, "min-gpu-clock"),
|
||||
ClockspeedType::MinMemoryClock => fl!(I18N, "min-vram-clock"),
|
||||
ClockspeedType::MinVoltage => fl!(I18N, "min-gpu-voltage"),
|
||||
ClockspeedType::VoltageOffset => fl!(I18N, "gpu-voltage-offset"),
|
||||
ClockspeedType::VoltageBoost => fl!(I18N, "gpu-voltage-boost"),
|
||||
ClockspeedType::GpuClockOffset(pstate) => fl!(I18N, "gpu-pstate-clock-offset", pstate = pstate),
|
||||
ClockspeedType::MemClockOffset(pstate) => fl!(I18N, "vram-pstate-clock-offset", pstate = pstate),
|
||||
ClockspeedType::GpuVfCurveClock(pstate) => fl!(I18N, "gpu-pstate-clock", pstate = pstate),
|
||||
ClockspeedType::MemVfCurveClock(pstate) => fl!(I18N, "mem-pstate-clock", pstate = pstate),
|
||||
ClockspeedType::GpuVfCurveVoltage(pstate) => fl!(I18N, "gpu-pstate-clock-voltage", pstate = pstate),
|
||||
ClockspeedType::MemVfCurveVoltage(pstate) => fl!(I18N, "mem-pstate-clock-voltage", pstate = pstate),
|
||||
ClockspeedType::Reset => unreachable!(),
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
gtk::MenuButton {
|
||||
set_icon_name: "dialog-information-symbolic",
|
||||
set_always_show_arrow: false,
|
||||
add_css_class: "flat",
|
||||
set_visible: self.clock_type == ClockspeedType::VoltageBoost,
|
||||
|
||||
#[wrap(Some)]
|
||||
set_popover = >k::Popover {
|
||||
gtk::Label {
|
||||
set_margin_all: 5,
|
||||
set_label: &fl!(I18N, "gpu-voltage-boost-tooltip"),
|
||||
set_wrap: true,
|
||||
set_wrap_mode: gtk::pango::WrapMode::Word,
|
||||
set_max_width_chars: 55,
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
gtk::Scale {
|
||||
set_adjustment: &self.adjustment,
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_hexpand: true,
|
||||
set_digits: 0,
|
||||
set_round_digits: 0,
|
||||
set_value_pos: gtk::PositionType::Right,
|
||||
set_width_request: 100,
|
||||
add_controller = make_event_controller_no_scroll(),
|
||||
},
|
||||
|
||||
#[name = "input_button"]
|
||||
gtk::SpinButton {
|
||||
set_adjustment: &self.adjustment,
|
||||
add_controller = make_event_controller_no_scroll(),
|
||||
connect_changed => move |_| {
|
||||
APP_BROKER.send(AppMsg::SettingsChanged);
|
||||
} @ text_change_signal,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn init_model(
|
||||
data: Self::Init,
|
||||
clock_type: &Self::Index,
|
||||
_sender: relm4::FactorySender<Self>,
|
||||
) -> Self {
|
||||
let adjustment = OcAdjustment::new(
|
||||
data.current as f64,
|
||||
data.min as f64,
|
||||
data.max as f64,
|
||||
data.step as f64,
|
||||
10.0,
|
||||
);
|
||||
|
||||
let change_signal = adjustment.connect_value_changed(move |_| {
|
||||
APP_BROKER.send(AppMsg::SettingsChanged);
|
||||
});
|
||||
|
||||
Self {
|
||||
clock_type: *clock_type,
|
||||
custom_title: data.custom_title,
|
||||
adjustment,
|
||||
change_signal,
|
||||
value_ratio: 1.0,
|
||||
is_secondary: data.is_secondary,
|
||||
}
|
||||
}
|
||||
|
||||
fn update_with_view(
|
||||
&mut self,
|
||||
widgets: &mut Self::Widgets,
|
||||
msg: Self::Input,
|
||||
sender: relm4::FactorySender<Self>,
|
||||
) {
|
||||
match msg {
|
||||
ClockAdjustmentRowMsg::ValueRatio(ratio) => {
|
||||
self.adjustment.block_signal(&self.change_signal);
|
||||
widgets
|
||||
.input_button
|
||||
.block_signal(&widgets.text_change_signal);
|
||||
|
||||
let raw_current = self.adjustment.value() / self.value_ratio;
|
||||
let raw_min = self.adjustment.lower() / self.value_ratio;
|
||||
let raw_max = self.adjustment.upper() / self.value_ratio;
|
||||
|
||||
self.adjustment.set_lower(raw_min * ratio);
|
||||
self.adjustment.set_upper(raw_max * ratio);
|
||||
self.adjustment.set_initial_value(raw_current * ratio);
|
||||
|
||||
self.value_ratio = ratio;
|
||||
|
||||
widgets
|
||||
.input_button
|
||||
.unblock_signal(&widgets.text_change_signal);
|
||||
self.adjustment.unblock_signal(&self.change_signal);
|
||||
}
|
||||
ClockAdjustmentRowMsg::AddSizeGroup {
|
||||
label_group,
|
||||
input_group,
|
||||
} => {
|
||||
label_group.add_widget(&widgets.title_box);
|
||||
input_group.add_widget(&widgets.input_button);
|
||||
}
|
||||
ClockAdjustmentRowMsg::SetValue(value) => {
|
||||
self.adjustment
|
||||
.set_value(f64::from(value) * self.value_ratio);
|
||||
}
|
||||
ClockAdjustmentRowMsg::SetVisible(visible) => {
|
||||
widgets.root_box.set_visible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
self.update_view(widgets, sender);
|
||||
}
|
||||
}
|
||||
|
||||
impl ClockAdjustmentRow {
|
||||
pub fn get_configured_value(&self) -> Option<i32> {
|
||||
self.adjustment
|
||||
.get_changed_value(false)
|
||||
.map(|value| (value / self.value_ratio) as i32)
|
||||
}
|
||||
|
||||
pub fn get_raw_value(&self) -> i32 {
|
||||
(self.adjustment.value() / self.value_ratio) as i32
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
mod adjustment_group;
|
||||
mod adjustment_row;
|
||||
|
||||
use crate::{
|
||||
APP_BROKER, I18N,
|
||||
app::{components::page_section::PageSection, msg::AppMsg, pages::oc_page::OcPageMsg},
|
||||
};
|
||||
use adjustment_group::{AdjustmentGroup, ClockCategory};
|
||||
use adjustment_row::ClocksData;
|
||||
use amdgpu_sysfs::gpu_handle::overdrive::ClocksTableGen as AmdClocksTable;
|
||||
use gtk::{
|
||||
glib::object::ObjectExt,
|
||||
@@ -38,6 +36,26 @@ pub struct ClocksFrame {
|
||||
enable_vram_locked_clocks: BoolBinding,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ClocksData {
|
||||
current: i32,
|
||||
min: i32,
|
||||
max: i32,
|
||||
custom_title: Option<String>,
|
||||
is_secondary: bool,
|
||||
}
|
||||
|
||||
impl ClocksData {
|
||||
fn new(current: i32, min: i32, max: i32) -> Self {
|
||||
Self {
|
||||
current,
|
||||
min,
|
||||
max,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClocksFrameInit {
|
||||
pub vf_curve_editing: BoolBinding,
|
||||
}
|
||||
@@ -636,7 +654,6 @@ impl ClocksFrame {
|
||||
current: voltage_boost.current,
|
||||
min: voltage_boost.min,
|
||||
max: voltage_boost.max,
|
||||
step: 1,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
@@ -709,3 +726,31 @@ fn nvidia_clock_offset_to_data(clock_info: &NvidiaClockOffset, is_secondary: boo
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn clock_title(clock_type: ClockspeedType) -> String {
|
||||
match clock_type {
|
||||
ClockspeedType::MaxCoreClock => fl!(I18N, "max-gpu-clock"),
|
||||
ClockspeedType::MaxMemoryClock => fl!(I18N, "max-vram-clock"),
|
||||
ClockspeedType::MaxVoltage => fl!(I18N, "max-gpu-voltage"),
|
||||
ClockspeedType::MinCoreClock => fl!(I18N, "min-gpu-clock"),
|
||||
ClockspeedType::MinMemoryClock => fl!(I18N, "min-vram-clock"),
|
||||
ClockspeedType::MinVoltage => fl!(I18N, "min-gpu-voltage"),
|
||||
ClockspeedType::VoltageOffset => fl!(I18N, "gpu-voltage-offset"),
|
||||
ClockspeedType::VoltageBoost => fl!(I18N, "gpu-voltage-boost"),
|
||||
ClockspeedType::GpuClockOffset(pstate) => {
|
||||
fl!(I18N, "gpu-pstate-clock-offset", pstate = pstate)
|
||||
}
|
||||
ClockspeedType::MemClockOffset(pstate) => {
|
||||
fl!(I18N, "vram-pstate-clock-offset", pstate = pstate)
|
||||
}
|
||||
ClockspeedType::GpuVfCurveClock(pstate) => fl!(I18N, "gpu-pstate-clock", pstate = pstate),
|
||||
ClockspeedType::MemVfCurveClock(pstate) => fl!(I18N, "mem-pstate-clock", pstate = pstate),
|
||||
ClockspeedType::GpuVfCurveVoltage(pstate) => {
|
||||
fl!(I18N, "gpu-pstate-clock-voltage", pstate = pstate)
|
||||
}
|
||||
ClockspeedType::MemVfCurveVoltage(pstate) => {
|
||||
fl!(I18N, "mem-pstate-clock-voltage", pstate = pstate)
|
||||
}
|
||||
ClockspeedType::Reset => unreachable!(),
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
APP_BROKER, I18N,
|
||||
app::{
|
||||
components::{oc_adjustment::OcAdjustment, page_section::PageSection},
|
||||
components::{adjustment_value::AdjustmentValue, page_section::PageSection},
|
||||
msg::AppMsg,
|
||||
pages::PageUpdate,
|
||||
},
|
||||
@@ -18,7 +18,7 @@ use std::fmt::Write;
|
||||
#[derive(Default)]
|
||||
pub struct PowerCapSection {
|
||||
power: PowerStats,
|
||||
adjustment: OcAdjustment,
|
||||
adjustment: AdjustmentValue,
|
||||
value_text: String,
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ impl relm4::Component for PowerCapSection {
|
||||
},
|
||||
|
||||
#[local_ref]
|
||||
adjustment -> OcAdjustment {
|
||||
adjustment -> AdjustmentValue {
|
||||
connect_value_notify => move |_| {
|
||||
APP_BROKER.send(AppMsg::SettingsChanged);
|
||||
} @ value_notify,
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::app::pages::PageUpdate;
|
||||
use crate::{
|
||||
APP_BROKER, I18N,
|
||||
app::{
|
||||
components::{oc_adjustment::OcAdjustment, page_section::PageSection},
|
||||
components::{adjustment_value::AdjustmentValue, page_section::PageSection},
|
||||
msg::AppMsg,
|
||||
utils::ext::{RelmLaunchable as _, make_event_controller_no_scroll},
|
||||
},
|
||||
@@ -61,17 +61,17 @@ pub struct ThermalsPage {
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct PmfwOptions {
|
||||
target_temperature: OcAdjustment,
|
||||
acoustic_limit: OcAdjustment,
|
||||
acoustic_target: OcAdjustment,
|
||||
minimum_pwm: OcAdjustment,
|
||||
zero_rpm_temperature: OcAdjustment,
|
||||
target_temperature: AdjustmentValue,
|
||||
acoustic_limit: AdjustmentValue,
|
||||
acoustic_target: AdjustmentValue,
|
||||
minimum_pwm: AdjustmentValue,
|
||||
zero_rpm_temperature: AdjustmentValue,
|
||||
zero_rpm_available: Rc<Cell<bool>>,
|
||||
zero_rpm: BoolBinding,
|
||||
}
|
||||
|
||||
impl PmfwOptions {
|
||||
fn adjustments(&self) -> [&OcAdjustment; 5] {
|
||||
fn adjustments(&self) -> [&AdjustmentValue; 5] {
|
||||
[
|
||||
&self.target_temperature,
|
||||
&self.acoustic_limit,
|
||||
@@ -88,12 +88,12 @@ impl PmfwOptions {
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct NvidiaThermalOptions {
|
||||
target_temperature: OcAdjustment,
|
||||
target_temperature: AdjustmentValue,
|
||||
target_temperaure_default: Option<u32>,
|
||||
}
|
||||
|
||||
impl NvidiaThermalOptions {
|
||||
fn adjustments(&self) -> [&OcAdjustment; 1] {
|
||||
fn adjustments(&self) -> [&AdjustmentValue; 1] {
|
||||
[&self.target_temperature]
|
||||
}
|
||||
}
|
||||
@@ -688,11 +688,11 @@ impl relm4::WidgetTemplate for FanSettingRow {
|
||||
}
|
||||
}
|
||||
|
||||
fn adj_is_empty(adj: &OcAdjustment) -> bool {
|
||||
fn adj_is_empty(adj: &AdjustmentValue) -> bool {
|
||||
adj.lower() == 0.0 && adj.upper() == 0.0
|
||||
}
|
||||
|
||||
fn set_fan_info(adjustment: &OcAdjustment, info: Option<FanInfo>) {
|
||||
fn set_fan_info(adjustment: &AdjustmentValue, info: Option<FanInfo>) {
|
||||
match info {
|
||||
Some(info) => {
|
||||
if let Some((min, max)) = info.allowed_range {
|
||||
|
||||
@@ -2,7 +2,8 @@ use super::{FanSettingRow, PmfwOptions, adj_is_empty};
|
||||
use crate::{
|
||||
APP_BROKER, I18N,
|
||||
app::{
|
||||
components::oc_adjustment::OcAdjustment, graphs_window::plot::PlotColorScheme, msg::AppMsg,
|
||||
components::adjustment_value::AdjustmentValue, graphs_window::plot::PlotColorScheme,
|
||||
msg::AppMsg,
|
||||
},
|
||||
};
|
||||
use gtk::{
|
||||
@@ -62,9 +63,9 @@ pub(super) struct FanCurveFrame {
|
||||
temp_keys: gtk::StringList,
|
||||
current_temp_key: U32Binding,
|
||||
|
||||
spindown_delay_adj: OcAdjustment,
|
||||
change_threshold_adj: OcAdjustment,
|
||||
auto_threshold_adj: OcAdjustment,
|
||||
spindown_delay_adj: AdjustmentValue,
|
||||
change_threshold_adj: AdjustmentValue,
|
||||
auto_threshold_adj: AdjustmentValue,
|
||||
change_signals: Rc<[(glib::Object, SignalHandlerId)]>,
|
||||
|
||||
is_dragging: Rc<AtomicBool>,
|
||||
@@ -323,10 +324,10 @@ impl relm4::Component for FanCurveFrame {
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
let spindown_delay_adj =
|
||||
OcAdjustment::new(DEFAULT_SPINDOWN_DELAY_MS as f64, 0.0, 30_000.0, 10.0, 10.0);
|
||||
AdjustmentValue::new(DEFAULT_SPINDOWN_DELAY_MS as f64, 0.0, 30_000.0, 10.0, 10.0);
|
||||
let change_threshold_adj =
|
||||
OcAdjustment::new(DEFAULT_CHANGE_THRESHOLD as f64, 0.0, 10.0, 1.0, 1.0);
|
||||
let auto_threshold_adj = OcAdjustment::new(0.0, 0.0, 0.0, 1.0, 5.0);
|
||||
AdjustmentValue::new(DEFAULT_CHANGE_THRESHOLD as f64, 0.0, 10.0, 1.0, 1.0);
|
||||
let auto_threshold_adj = AdjustmentValue::new(0.0, 0.0, 0.0, 1.0, 5.0);
|
||||
let temp_keys = gtk::StringList::default();
|
||||
let current_temp_key = U32Binding::new(0u32);
|
||||
|
||||
|
||||
Reference in new issue
Block a user