mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
refactor: make info page a relm component (#404)
* refactor: drop RootStack * refactor: make InformationPage a relm component
This commit is contained in:
parent
41f26c7f34
commit
23ab0e86e8
@ -23,7 +23,6 @@ use lact_schema::{
|
||||
use libdrm_amdgpu_sys::AMDGPU::ThrottlerBit;
|
||||
use pciid_parser::Database;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
cell::RefCell,
|
||||
cmp,
|
||||
collections::{HashMap, HashSet},
|
||||
@ -551,7 +550,7 @@ impl GpuController for AmdGpuController {
|
||||
}
|
||||
}
|
||||
});
|
||||
let pci_info = self.pci_info.as_ref().map(Cow::Borrowed);
|
||||
let pci_info = self.pci_info.clone();
|
||||
let driver = self.handle.get_driver().to_owned();
|
||||
let vbios_version = self.get_full_vbios_version();
|
||||
let link_info = self.get_link_info();
|
||||
|
@ -21,7 +21,6 @@ use nvml_wrapper::{
|
||||
Device, Nvml,
|
||||
};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
cell::RefCell,
|
||||
collections::HashMap,
|
||||
fmt::Write,
|
||||
@ -292,7 +291,7 @@ impl GpuController for NvidiaGpuController {
|
||||
};
|
||||
|
||||
DeviceInfo {
|
||||
pci_info: Some(Cow::Borrowed(&self.pci_info)),
|
||||
pci_info: Some(self.pci_info.clone()),
|
||||
vulkan_info,
|
||||
driver: format!(
|
||||
"nvidia {}",
|
||||
|
@ -306,7 +306,7 @@ impl<'a> Handler {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_device_info(&'a self, id: &str) -> anyhow::Result<DeviceInfo<'a>> {
|
||||
pub fn get_device_info(&'a self, id: &str) -> anyhow::Result<DeviceInfo> {
|
||||
Ok(self.controller_by_id(id)?.get_info())
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ mod header;
|
||||
mod info_row;
|
||||
mod msg;
|
||||
mod page_section;
|
||||
mod root_stack;
|
||||
mod pages;
|
||||
|
||||
use crate::{APP_ID, GUI_VERSION};
|
||||
use anyhow::{anyhow, Context};
|
||||
@ -30,12 +30,15 @@ use lact_schema::{
|
||||
FanOptions, GIT_COMMIT,
|
||||
};
|
||||
use msg::AppMsg;
|
||||
use pages::{
|
||||
info_page::InformationPage, oc_page::OcPage, software_page::SoftwarePage,
|
||||
thermals_page::ThermalsPage, PageUpdate,
|
||||
};
|
||||
use relm4::{
|
||||
actions::{RelmAction, RelmActionGroup},
|
||||
prelude::{AsyncComponent, AsyncComponentParts},
|
||||
tokio, AsyncComponentSender, Component, ComponentController,
|
||||
};
|
||||
use root_stack::RootStack;
|
||||
use std::{os::unix::net::UnixStream, rc::Rc, sync::atomic::AtomicBool, time::Duration};
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
|
||||
@ -44,7 +47,12 @@ const STATS_POLL_INTERVAL_MS: u64 = 250;
|
||||
pub struct AppModel {
|
||||
daemon_client: DaemonClient,
|
||||
graphs_window: GraphsWindow,
|
||||
root_stack: RootStack,
|
||||
|
||||
info_page: relm4::Controller<InformationPage>,
|
||||
oc_page: OcPage,
|
||||
thermals_page: ThermalsPage,
|
||||
software_page: relm4::Controller<SoftwarePage>,
|
||||
|
||||
header: relm4::Controller<Header>,
|
||||
apply_revealer: relm4::Controller<ApplyRevealer>,
|
||||
stats_task_handle: Option<glib::JoinHandle<()>>,
|
||||
@ -72,7 +80,19 @@ impl AsyncComponent for AppModel {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
|
||||
model.root_stack.container.clone(),
|
||||
#[name = "root_stack"]
|
||||
gtk::Stack {
|
||||
set_vexpand: true,
|
||||
set_margin_top: 15,
|
||||
set_margin_start: 30,
|
||||
set_margin_end: 30,
|
||||
|
||||
add_titled[Some("info_page"), "Information"] = model.info_page.widget(),
|
||||
add_titled[Some("oc_page"), "OC"] = &model.oc_page.container.clone(),
|
||||
add_titled[Some("thermals_page"), "Thermals"] = &model.thermals_page.container.clone(),
|
||||
add_titled[Some("software_page"), "Software"] = model.software_page.widget(),
|
||||
},
|
||||
|
||||
model.apply_revealer.widget(),
|
||||
}
|
||||
},
|
||||
@ -145,24 +165,31 @@ impl AsyncComponent for AppModel {
|
||||
sender.input(AppMsg::Error(err.into()));
|
||||
}
|
||||
|
||||
let root_stack = RootStack::new(system_info, daemon_client.embedded);
|
||||
let info_page = InformationPage::builder().launch(()).detach();
|
||||
|
||||
let oc_page = OcPage::new(&system_info);
|
||||
let thermals_page = ThermalsPage::new(&system_info);
|
||||
|
||||
let software_page = SoftwarePage::builder()
|
||||
.launch((system_info, daemon_client.embedded))
|
||||
.detach();
|
||||
|
||||
let header = Header::builder()
|
||||
.launch((devices, root_stack.container.clone()))
|
||||
.launch(devices)
|
||||
.forward(sender.input_sender(), |msg| msg);
|
||||
|
||||
let apply_revealer = ApplyRevealer::builder()
|
||||
.launch(())
|
||||
.forward(sender.input_sender(), |msg| msg);
|
||||
|
||||
root_stack.oc_page.clocks_frame.connect_clocks_reset(clone!(
|
||||
oc_page.clocks_frame.connect_clocks_reset(clone!(
|
||||
#[strong]
|
||||
sender,
|
||||
move || {
|
||||
sender.input(AppMsg::ResetClocks);
|
||||
}
|
||||
));
|
||||
root_stack.thermals_page.connect_reset_pmfw(clone!(
|
||||
thermals_page.connect_reset_pmfw(clone!(
|
||||
#[strong]
|
||||
sender,
|
||||
move || {
|
||||
@ -170,7 +197,7 @@ impl AsyncComponent for AppModel {
|
||||
}
|
||||
));
|
||||
|
||||
if let Some(ref button) = root_stack.oc_page.enable_overclocking_button {
|
||||
if let Some(ref button) = oc_page.enable_overclocking_button {
|
||||
button.connect_clicked(clone!(
|
||||
#[strong]
|
||||
sender,
|
||||
@ -190,7 +217,10 @@ impl AsyncComponent for AppModel {
|
||||
let model = AppModel {
|
||||
daemon_client,
|
||||
graphs_window,
|
||||
root_stack,
|
||||
info_page,
|
||||
oc_page,
|
||||
thermals_page,
|
||||
software_page,
|
||||
apply_revealer,
|
||||
header,
|
||||
stats_task_handle: None,
|
||||
@ -202,6 +232,9 @@ impl AsyncComponent for AppModel {
|
||||
show_embedded_info(&root, err);
|
||||
}
|
||||
|
||||
model
|
||||
.header
|
||||
.emit(HeaderMsg::Stack(widgets.root_stack.clone()));
|
||||
sender.input(AppMsg::ReloadProfiles);
|
||||
|
||||
AsyncComponentParts { model, widgets }
|
||||
@ -260,9 +293,10 @@ impl AppModel {
|
||||
sender.input(AppMsg::ReloadProfiles);
|
||||
}
|
||||
AppMsg::Stats(stats) => {
|
||||
self.root_stack.info_page.set_stats(&stats);
|
||||
self.root_stack.thermals_page.set_stats(&stats, false);
|
||||
self.root_stack.oc_page.set_stats(&stats, false);
|
||||
self.info_page.emit(PageUpdate::Stats(stats.clone()));
|
||||
|
||||
self.thermals_page.set_stats(&stats, false);
|
||||
self.oc_page.set_stats(&stats, false);
|
||||
self.graphs_window.set_stats(&stats);
|
||||
}
|
||||
AppMsg::ApplyChanges => {
|
||||
@ -355,10 +389,11 @@ impl AppModel {
|
||||
.get_device_info(&gpu_id)
|
||||
.await
|
||||
.context("Could not fetch info")?;
|
||||
let info = info_buf.inner()?;
|
||||
let info = Rc::new(info_buf.inner()?);
|
||||
|
||||
self.root_stack.info_page.set_info(&info);
|
||||
self.root_stack.oc_page.set_info(&info);
|
||||
self.info_page.emit(PageUpdate::Info(info.clone()));
|
||||
|
||||
self.oc_page.set_info(&info);
|
||||
|
||||
let vram_clock_ratio = info
|
||||
.drm_info
|
||||
@ -369,7 +404,7 @@ impl AppModel {
|
||||
|
||||
self.update_gpu_data(gpu_id, sender).await?;
|
||||
|
||||
self.root_stack.thermals_page.set_info(&info);
|
||||
self.thermals_page.set_info(&info);
|
||||
|
||||
self.graphs_window.clear();
|
||||
|
||||
@ -393,10 +428,12 @@ impl AppModel {
|
||||
.await
|
||||
.context("Could not fetch stats")?
|
||||
.inner()?;
|
||||
let stats = Rc::new(stats);
|
||||
|
||||
self.root_stack.oc_page.set_stats(&stats, true);
|
||||
self.root_stack.thermals_page.set_stats(&stats, true);
|
||||
self.root_stack.info_page.set_stats(&stats);
|
||||
self.oc_page.set_stats(&stats, true);
|
||||
self.thermals_page.set_stats(&stats, true);
|
||||
|
||||
self.info_page.emit(PageUpdate::Stats(stats));
|
||||
|
||||
let maybe_clocks_table = match self.daemon_client.get_device_clocks_info(&gpu_id).await {
|
||||
Ok(clocks_buf) => match clocks_buf.inner() {
|
||||
@ -411,7 +448,7 @@ impl AppModel {
|
||||
None
|
||||
}
|
||||
};
|
||||
self.root_stack.oc_page.set_clocks_table(maybe_clocks_table);
|
||||
self.oc_page.set_clocks_table(maybe_clocks_table);
|
||||
|
||||
let maybe_modes_table = match self
|
||||
.daemon_client
|
||||
@ -430,8 +467,7 @@ impl AppModel {
|
||||
None
|
||||
}
|
||||
};
|
||||
self.root_stack
|
||||
.oc_page
|
||||
self.oc_page
|
||||
.performance_frame
|
||||
.set_power_profile_modes(maybe_modes_table);
|
||||
|
||||
@ -442,8 +478,7 @@ impl AppModel {
|
||||
.and_then(|states| states.inner())
|
||||
{
|
||||
Ok(power_states) => {
|
||||
self.root_stack
|
||||
.oc_page
|
||||
self.oc_page
|
||||
.power_states_frame
|
||||
.set_power_states(power_states);
|
||||
}
|
||||
@ -460,13 +495,10 @@ impl AppModel {
|
||||
}
|
||||
);
|
||||
|
||||
self.root_stack
|
||||
.thermals_page
|
||||
self.thermals_page
|
||||
.connect_settings_changed(show_revealer.clone());
|
||||
|
||||
self.root_stack
|
||||
.oc_page
|
||||
.connect_settings_changed(show_revealer);
|
||||
self.oc_page.connect_settings_changed(show_revealer);
|
||||
|
||||
self.apply_revealer
|
||||
.sender()
|
||||
@ -492,7 +524,7 @@ impl AppModel {
|
||||
|
||||
debug!("applying settings on gpu {gpu_id}");
|
||||
|
||||
if let Some(cap) = self.root_stack.oc_page.get_power_cap() {
|
||||
if let Some(cap) = self.oc_page.get_power_cap() {
|
||||
self.daemon_client
|
||||
.set_power_cap(&gpu_id, Some(cap))
|
||||
.await
|
||||
@ -514,7 +546,7 @@ impl AppModel {
|
||||
.await
|
||||
.context("Could not commit config")?;
|
||||
|
||||
if let Some(level) = self.root_stack.oc_page.get_performance_level() {
|
||||
if let Some(level) = self.oc_page.get_performance_level() {
|
||||
self.daemon_client
|
||||
.set_performance_level(&gpu_id, level)
|
||||
.await
|
||||
@ -525,12 +557,10 @@ impl AppModel {
|
||||
.context("Could not commit config")?;
|
||||
|
||||
let mode_index = self
|
||||
.root_stack
|
||||
.oc_page
|
||||
.performance_frame
|
||||
.get_selected_power_profile_mode();
|
||||
let custom_heuristics = self
|
||||
.root_stack
|
||||
.oc_page
|
||||
.performance_frame
|
||||
.get_power_profile_mode_custom_heuristics();
|
||||
@ -545,7 +575,7 @@ impl AppModel {
|
||||
.context("Could not commit config")?;
|
||||
}
|
||||
|
||||
if let Some(thermals_settings) = self.root_stack.thermals_page.get_thermals_settings() {
|
||||
if let Some(thermals_settings) = self.thermals_page.get_thermals_settings() {
|
||||
debug!("applying thermal settings: {thermals_settings:?}");
|
||||
let opts = FanOptions {
|
||||
id: &gpu_id,
|
||||
@ -568,7 +598,7 @@ impl AppModel {
|
||||
.context("Could not commit config")?;
|
||||
}
|
||||
|
||||
let clocks_settings = self.root_stack.oc_page.clocks_frame.get_settings();
|
||||
let clocks_settings = self.oc_page.clocks_frame.get_settings();
|
||||
let mut clocks_commands = Vec::new();
|
||||
|
||||
debug!("applying clocks settings {clocks_settings:#?}");
|
||||
@ -601,7 +631,7 @@ impl AppModel {
|
||||
clocks_commands.push(SetClocksCommand::VoltageOffset(offset));
|
||||
}
|
||||
|
||||
let enabled_power_states = self.root_stack.oc_page.get_enabled_power_states();
|
||||
let enabled_power_states = self.oc_page.get_enabled_power_states();
|
||||
|
||||
for (kind, states) in enabled_power_states {
|
||||
if !states.is_empty() {
|
||||
@ -896,7 +926,7 @@ fn start_stats_update_loop(
|
||||
.and_then(|buffer| buffer.inner())
|
||||
{
|
||||
Ok(stats) => {
|
||||
sender.input(AppMsg::Stats(stats));
|
||||
sender.input(AppMsg::Stats(Rc::new(stats)));
|
||||
}
|
||||
Err(err) => {
|
||||
error!("could not fetch stats: {err:#}");
|
||||
|
@ -17,10 +17,12 @@ pub struct Header {
|
||||
gpu_selector: TypedListView<GpuListItem, gtk::SingleSelection>,
|
||||
profile_selector: TypedListView<ProfileListItem, gtk::SingleSelection>,
|
||||
selector_label: String,
|
||||
stack: Option<Stack>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum HeaderMsg {
|
||||
Stack(Stack),
|
||||
Profiles(ProfilesInfo),
|
||||
SelectProfile,
|
||||
SelectGpu,
|
||||
@ -30,7 +32,7 @@ pub enum HeaderMsg {
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl Component for Header {
|
||||
type Init = (Vec<DeviceListEntry>, gtk::Stack);
|
||||
type Init = Vec<DeviceListEntry>;
|
||||
type Input = HeaderMsg;
|
||||
type Output = AppMsg;
|
||||
type CommandOutput = ();
|
||||
@ -41,7 +43,8 @@ impl Component for Header {
|
||||
|
||||
#[wrap(Some)]
|
||||
set_title_widget = &StackSwitcher {
|
||||
set_stack: Some(&stack),
|
||||
#[watch]
|
||||
set_stack: model.stack.as_ref(),
|
||||
},
|
||||
|
||||
#[name = "menu_button"]
|
||||
@ -137,7 +140,7 @@ impl Component for Header {
|
||||
}
|
||||
|
||||
fn init(
|
||||
(variants, stack): Self::Init,
|
||||
variants: Self::Init,
|
||||
root: Self::Root,
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
@ -171,6 +174,7 @@ impl Component for Header {
|
||||
gpu_selector,
|
||||
profile_selector,
|
||||
selector_label: String::new(),
|
||||
stack: None,
|
||||
};
|
||||
|
||||
let gpu_selector = &model.gpu_selector.view;
|
||||
@ -208,6 +212,9 @@ impl Component for Header {
|
||||
_root: &Self::Root,
|
||||
) {
|
||||
match msg {
|
||||
HeaderMsg::Stack(stack) => {
|
||||
self.stack = Some(stack);
|
||||
}
|
||||
HeaderMsg::Profiles(profiles_info) => {
|
||||
let selected_index = match &profiles_info.current_profile {
|
||||
Some(profile) => {
|
||||
|
@ -7,7 +7,7 @@ use std::rc::Rc;
|
||||
pub enum AppMsg {
|
||||
Error(Rc<anyhow::Error>),
|
||||
ReloadData { full: bool },
|
||||
Stats(DeviceStats),
|
||||
Stats(Rc<DeviceStats>),
|
||||
ApplyChanges,
|
||||
RevertChanges,
|
||||
ResetClocks,
|
||||
|
49
lact-gui/src/app/pages.rs
Normal file
49
lact-gui/src/app/pages.rs
Normal file
@ -0,0 +1,49 @@
|
||||
pub mod info_page;
|
||||
pub mod oc_adjustment;
|
||||
pub mod oc_page;
|
||||
pub mod software_page;
|
||||
pub mod thermals_page;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use gtk::{prelude::*, *};
|
||||
use lact_schema::{DeviceInfo, DeviceStats};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PageUpdate {
|
||||
Info(Rc<DeviceInfo>),
|
||||
Stats(Rc<DeviceStats>),
|
||||
}
|
||||
|
||||
fn values_row<W: IsA<Widget>>(
|
||||
title: &str,
|
||||
parent: &Grid,
|
||||
value_child: &W,
|
||||
row: i32,
|
||||
column_offset: i32,
|
||||
) {
|
||||
let title_label = Label::builder().label(title).halign(Align::Start).build();
|
||||
|
||||
parent.attach(&title_label, column_offset, row, 1, 1);
|
||||
parent.attach(value_child, column_offset + 1, row, 1, 1);
|
||||
}
|
||||
|
||||
fn label_row(title: &str, parent: &Grid, row: i32, column_offset: i32, selectable: bool) -> Label {
|
||||
let value_label = Label::builder()
|
||||
.halign(Align::End)
|
||||
.hexpand(true)
|
||||
.selectable(selectable)
|
||||
.build();
|
||||
values_row(title, parent, &value_label, row, column_offset);
|
||||
|
||||
value_label
|
||||
}
|
||||
|
||||
fn values_grid() -> Grid {
|
||||
Grid::builder()
|
||||
.margin_start(10)
|
||||
.margin_end(5)
|
||||
.row_spacing(10)
|
||||
.column_spacing(10)
|
||||
.build()
|
||||
}
|
96
lact-gui/src/app/pages/info_page.rs
Normal file
96
lact-gui/src/app/pages/info_page.rs
Normal file
@ -0,0 +1,96 @@
|
||||
mod hardware_info;
|
||||
mod vulkan_info;
|
||||
|
||||
use self::hardware_info::HardwareInfoSection;
|
||||
use super::{values_grid, PageUpdate};
|
||||
use crate::app::page_section::PageSection;
|
||||
use gtk::prelude::*;
|
||||
use relm4::{Component, ComponentParts, ComponentSender, RelmWidgetExt};
|
||||
use vulkan_info::VulkanInfoFrame;
|
||||
|
||||
pub struct InformationPage {
|
||||
hardware_info: HardwareInfoSection,
|
||||
vulkan_info: VulkanInfoFrame,
|
||||
}
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl Component for InformationPage {
|
||||
type Init = ();
|
||||
type Input = PageUpdate;
|
||||
type Output = ();
|
||||
type CommandOutput = ();
|
||||
|
||||
view! {
|
||||
gtk::ScrolledWindow {
|
||||
set_hscrollbar_policy: gtk::PolicyType::Never,
|
||||
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 15,
|
||||
set_margin_horizontal: 20,
|
||||
|
||||
model.hardware_info.clone(),
|
||||
|
||||
#[name = "vulkan_section"]
|
||||
PageSection::new("Vulkan Information") -> PageSection {
|
||||
set_spacing: 10,
|
||||
set_margin_start: 15,
|
||||
|
||||
append = &model.vulkan_info.container.clone(),
|
||||
},
|
||||
|
||||
#[name = "vulkan_unavailable_label"]
|
||||
gtk::Label {
|
||||
set_label: "Vulkan is not available on this GPU",
|
||||
set_visible: false,
|
||||
set_margin_horizontal: 10,
|
||||
set_halign: gtk::Align::Start,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn init(
|
||||
_init: Self::Init,
|
||||
root: Self::Root,
|
||||
_sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
let hardware_info = HardwareInfoSection::new();
|
||||
let vulkan_info = VulkanInfoFrame::new();
|
||||
|
||||
let model = Self {
|
||||
hardware_info,
|
||||
vulkan_info,
|
||||
};
|
||||
|
||||
let widgets = view_output!();
|
||||
|
||||
ComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
fn update_with_view(
|
||||
&mut self,
|
||||
widgets: &mut Self::Widgets,
|
||||
msg: Self::Input,
|
||||
_sender: ComponentSender<Self>,
|
||||
_root: &Self::Root,
|
||||
) {
|
||||
match msg {
|
||||
PageUpdate::Info(gpu_info) => {
|
||||
self.hardware_info.set_info(&gpu_info);
|
||||
|
||||
if let Some(vulkan_info) = &gpu_info.vulkan_info {
|
||||
self.vulkan_info.set_info(vulkan_info);
|
||||
self.vulkan_info.container.show();
|
||||
widgets.vulkan_unavailable_label.hide();
|
||||
} else {
|
||||
self.vulkan_info.container.hide();
|
||||
widgets.vulkan_unavailable_label.show();
|
||||
}
|
||||
}
|
||||
PageUpdate::Stats(stats) => {
|
||||
self.hardware_info.set_stats(&stats);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@ impl HardwareInfoSection {
|
||||
.drm_info
|
||||
.as_ref()
|
||||
.and_then(|drm| drm.device_name.as_deref())
|
||||
.or_else(|| pci_info.device_pci_info.model.as_deref())
|
||||
.or(pci_info.device_pci_info.model.as_deref())
|
||||
.unwrap_or("Unknown")
|
||||
.to_owned();
|
||||
|
@ -105,7 +105,7 @@ impl SimpleComponent for VulkanFeaturesWindow {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct VulkanFeature {
|
||||
pub name: String,
|
||||
pub supported: bool,
|
@ -1,7 +1,7 @@
|
||||
mod feature_window;
|
||||
|
||||
use super::values_grid;
|
||||
use crate::app::root_stack::{label_row, values_row};
|
||||
use crate::app::pages::{label_row, values_row};
|
||||
use feature_window::{VulkanFeature, VulkanFeaturesWindow};
|
||||
use glib::clone;
|
||||
use gtk::prelude::*;
|
||||
@ -12,7 +12,7 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use tracing::trace;
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct VulkanInfoFrame {
|
||||
pub container: Box,
|
||||
device_name_label: Label,
|
@ -1,7 +1,7 @@
|
||||
mod adjustment_row;
|
||||
|
||||
use crate::app::page_section::PageSection;
|
||||
use crate::app::root_stack::oc_adjustment::OcAdjustment;
|
||||
use crate::app::pages::oc_adjustment::OcAdjustment;
|
||||
use adjustment_row::AdjustmentRow;
|
||||
use amdgpu_sysfs::gpu_handle::overdrive::{ClocksTable as _, ClocksTableGen as AmdClocksTable};
|
||||
use glib::clone;
|
@ -56,7 +56,7 @@ impl AdjustmentRow {
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use crate::app::root_stack::oc_adjustment::OcAdjustment;
|
||||
use crate::app::pages::oc_adjustment::OcAdjustment;
|
||||
use glib::{clone, subclass::InitializingObject};
|
||||
use gtk::{
|
||||
glib::{self, Properties},
|
@ -29,7 +29,7 @@ impl Default for PowerCapSection {
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use crate::app::{page_section::PageSection, root_stack::oc_adjustment::OcAdjustment};
|
||||
use crate::app::{page_section::PageSection, pages::oc_adjustment::OcAdjustment};
|
||||
use gtk::{
|
||||
glib::{self, clone, subclass::InitializingObject, types::StaticTypeExt, Properties},
|
||||
prelude::{ButtonExt, ObjectExt},
|
@ -66,7 +66,7 @@ impl Default for PowerStatesFrame {
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use crate::app::root_stack::oc_page::power_states::power_states_list::PowerStatesList;
|
||||
use crate::app::pages::oc_page::power_states::power_states_list::PowerStatesList;
|
||||
use gtk::{
|
||||
glib::{self, subclass::InitializingObject, types::StaticTypeExt, Properties},
|
||||
prelude::ObjectExt,
|
@ -1,4 +1,4 @@
|
||||
use crate::app::root_stack::oc_page::power_states::power_state_row::PowerStateRow;
|
||||
use crate::app::pages::oc_page::power_states::power_state_row::PowerStateRow;
|
||||
use gtk::{
|
||||
gio,
|
||||
glib::{
|
@ -1,7 +1,7 @@
|
||||
mod point_adjustment;
|
||||
|
||||
use self::point_adjustment::PointAdjustment;
|
||||
use crate::app::root_stack::oc_adjustment::OcAdjustment;
|
||||
use crate::app::pages::oc_adjustment::OcAdjustment;
|
||||
use glib::clone;
|
||||
use gtk::graphene::Point;
|
||||
use gtk::gsk::Transform;
|
@ -1,4 +1,4 @@
|
||||
use crate::app::root_stack::oc_adjustment::OcAdjustment;
|
||||
use crate::app::pages::oc_adjustment::OcAdjustment;
|
||||
use amdgpu_sysfs::gpu_handle::fan_control::FanInfo;
|
||||
use gtk::{
|
||||
glib::clone,
|
@ -1,80 +0,0 @@
|
||||
mod hardware_info;
|
||||
mod vulkan_info;
|
||||
|
||||
use self::hardware_info::HardwareInfoSection;
|
||||
|
||||
use super::values_grid;
|
||||
use crate::app::page_section::PageSection;
|
||||
use gtk::prelude::*;
|
||||
use gtk::*;
|
||||
use lact_client::schema::{DeviceInfo, DeviceStats};
|
||||
use vulkan_info::VulkanInfoFrame;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InformationPage {
|
||||
pub container: ScrolledWindow,
|
||||
hardware_info: HardwareInfoSection,
|
||||
vulkan_info_frame: VulkanInfoFrame,
|
||||
vulkan_unavailable_label: Label,
|
||||
}
|
||||
|
||||
impl InformationPage {
|
||||
pub fn new() -> Self {
|
||||
let vbox = Box::builder()
|
||||
.orientation(Orientation::Vertical)
|
||||
.spacing(15)
|
||||
.margin_start(20)
|
||||
.margin_end(20)
|
||||
.build();
|
||||
|
||||
let hardware_info = HardwareInfoSection::new();
|
||||
vbox.append(&hardware_info);
|
||||
|
||||
let vulkan_container = PageSection::new("Vulkan Information");
|
||||
vulkan_container.set_spacing(10);
|
||||
vulkan_container.set_margin_start(15);
|
||||
|
||||
let vulkan_info_frame = VulkanInfoFrame::new();
|
||||
vulkan_container.append(&vulkan_info_frame.container);
|
||||
|
||||
let vulkan_unavailable_label = Label::builder()
|
||||
.label("Vulkan is not available on this GPU")
|
||||
.visible(false)
|
||||
.margin_start(10)
|
||||
.margin_end(10)
|
||||
.halign(Align::Start)
|
||||
.build();
|
||||
vulkan_container.append(&vulkan_unavailable_label);
|
||||
|
||||
vbox.append(&vulkan_container);
|
||||
|
||||
let container = ScrolledWindow::builder()
|
||||
.hscrollbar_policy(PolicyType::Never)
|
||||
.child(&vbox)
|
||||
.build();
|
||||
|
||||
Self {
|
||||
container,
|
||||
hardware_info,
|
||||
vulkan_info_frame,
|
||||
vulkan_unavailable_label,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_info(&self, gpu_info: &DeviceInfo) {
|
||||
self.hardware_info.set_info(gpu_info);
|
||||
|
||||
if let Some(vulkan_info) = &gpu_info.vulkan_info {
|
||||
self.vulkan_info_frame.set_info(vulkan_info);
|
||||
self.vulkan_info_frame.container.show();
|
||||
self.vulkan_unavailable_label.hide();
|
||||
} else {
|
||||
self.vulkan_info_frame.container.hide();
|
||||
self.vulkan_unavailable_label.show();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_stats(&self, stats: &DeviceStats) {
|
||||
self.hardware_info.set_stats(stats);
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
mod info_page;
|
||||
mod oc_adjustment;
|
||||
mod oc_page;
|
||||
mod software_page;
|
||||
mod thermals_page;
|
||||
|
||||
use gtk::{prelude::*, *};
|
||||
use relm4::{Component, ComponentController};
|
||||
|
||||
use self::software_page::SoftwarePage;
|
||||
use info_page::InformationPage;
|
||||
use lact_client::schema::SystemInfo;
|
||||
use oc_page::OcPage;
|
||||
use thermals_page::ThermalsPage;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RootStack {
|
||||
pub container: Stack,
|
||||
pub info_page: InformationPage,
|
||||
pub thermals_page: ThermalsPage,
|
||||
pub oc_page: OcPage,
|
||||
}
|
||||
|
||||
impl RootStack {
|
||||
pub fn new(system_info: SystemInfo, embedded_daemon: bool) -> Self {
|
||||
let container = Stack::builder()
|
||||
.vexpand(true)
|
||||
.margin_top(15)
|
||||
.margin_start(30)
|
||||
.margin_end(30)
|
||||
.build();
|
||||
|
||||
let info_page = InformationPage::new();
|
||||
|
||||
container.add_titled(&info_page.container, Some("info_page"), "Information");
|
||||
|
||||
let oc_page = OcPage::new(&system_info);
|
||||
|
||||
container.add_titled(&oc_page.container, Some("oc_page"), "OC");
|
||||
|
||||
let thermals_page = ThermalsPage::new(&system_info);
|
||||
|
||||
container.add_titled(&thermals_page.container, Some("thermals_page"), "Thermals");
|
||||
|
||||
let mut software_page = SoftwarePage::builder()
|
||||
.launch((system_info, embedded_daemon))
|
||||
.detach();
|
||||
container.add_titled(software_page.widget(), Some("software_page"), "Software");
|
||||
software_page.detach_runtime();
|
||||
|
||||
Self {
|
||||
container,
|
||||
info_page,
|
||||
thermals_page,
|
||||
oc_page,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn values_row<W: IsA<Widget>>(
|
||||
title: &str,
|
||||
parent: &Grid,
|
||||
value_child: &W,
|
||||
row: i32,
|
||||
column_offset: i32,
|
||||
) {
|
||||
let title_label = Label::builder().label(title).halign(Align::Start).build();
|
||||
|
||||
parent.attach(&title_label, column_offset, row, 1, 1);
|
||||
parent.attach(value_child, column_offset + 1, row, 1, 1);
|
||||
}
|
||||
|
||||
fn label_row(title: &str, parent: &Grid, row: i32, column_offset: i32, selectable: bool) -> Label {
|
||||
let value_label = Label::builder()
|
||||
.halign(Align::End)
|
||||
.hexpand(true)
|
||||
.selectable(selectable)
|
||||
.build();
|
||||
values_row(title, parent, &value_label, row, column_offset);
|
||||
|
||||
value_label
|
||||
}
|
||||
|
||||
fn values_grid() -> Grid {
|
||||
Grid::builder()
|
||||
.margin_start(10)
|
||||
.margin_end(5)
|
||||
.row_spacing(10)
|
||||
.column_spacing(10)
|
||||
.build()
|
||||
}
|
@ -89,9 +89,8 @@ pub struct GpuPciInfo {
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct DeviceInfo<'a> {
|
||||
#[serde(borrow)]
|
||||
pub pci_info: Option<Cow<'a, GpuPciInfo>>,
|
||||
pub struct DeviceInfo {
|
||||
pub pci_info: Option<GpuPciInfo>,
|
||||
pub vulkan_info: Option<VulkanInfo>,
|
||||
pub driver: String,
|
||||
pub vbios_version: Option<String>,
|
||||
|
Loading…
Reference in New Issue
Block a user