diff --git a/lact-daemon/src/tests/snapshots/lact_daemon__tests__amd__rx7700s.snap b/lact-daemon/src/tests/snapshots/lact_daemon__tests__amd__rx7700s.snap index 02f1ec2b..2a2470c4 100644 --- a/lact-daemon/src/tests/snapshots/lact_daemon__tests__amd__rx7700s.snap +++ b/lact-daemon/src/tests/snapshots/lact_daemon__tests__amd__rx7700s.snap @@ -46,84 +46,19 @@ expression: device_info { "clock_type": null, "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 4 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 800 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 3 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ + 0, + 0, + 0, + 1, + 4, + 0, + 800, + 0, + 0, + 0, + 3, + 1, + 0, 0 ] } @@ -135,84 +70,19 @@ expression: device_info { "clock_type": null, "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 2 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 4 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 650 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ + 0, + 2, + 0, + 1, + 4, + 0, + 650, + 0, + 0, + 0, + 1, + 1, + 0, 0 ] } @@ -224,84 +94,19 @@ expression: device_info { "clock_type": null, "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 3 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ + 0, + 0, + 0, + 1, + 3, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, 0 ] } @@ -313,84 +118,19 @@ expression: device_info { "clock_type": null, "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 4 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ + 0, + 0, + 0, + 1, + 4, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, 0 ] } @@ -402,84 +142,19 @@ expression: device_info { "clock_type": null, "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 4 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 1000 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ + 0, + 1, + 0, + 4, + 1, + 1000, + 0, + 0, + 0, + 0, + 1, + 1, + 0, 0 ] } @@ -491,84 +166,19 @@ expression: device_info { "clock_type": null, "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 4 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 1000 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ + 0, + 1, + 0, + 4, + 1, + 1000, + 0, + 0, + 0, + 0, + 1, + 1, + 0, 0 ] } @@ -580,84 +190,19 @@ expression: device_info { "clock_type": null, "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 4 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 800 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 3 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ + 0, + 0, + 0, + 1, + 4, + 0, + 800, + 0, + 0, + 0, + 3, + 1, + 0, 0 ] } @@ -669,84 +214,19 @@ expression: device_info { "clock_type": null, "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 2 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 4 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 650 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ - 3 - ] - }, - { - "clock_type": null, - "values": [ - 1 - ] - }, - { - "clock_type": null, - "values": [ - 0 - ] - }, - { - "clock_type": null, - "values": [ + 0, + 2, + 0, + 1, + 4, + 0, + 650, + 0, + 0, + 0, + 3, + 1, + 0, 0 ] } @@ -787,6 +267,7 @@ expression: device_info "speed_min": 0 }, "memory_power_state": 0, + "performance_level": "auto", "power": { "average": 1.0, "cap_current": 100.0, diff --git a/lact-gui/src/app.rs b/lact-gui/src/app.rs index a22eae01..a475fb4c 100644 --- a/lact-gui/src/app.rs +++ b/lact-gui/src/app.rs @@ -11,7 +11,7 @@ use crate::{APP_ID, GUI_VERSION}; use anyhow::{anyhow, Context}; use apply_revealer::{ApplyRevealer, ApplyRevealerMsg}; use confirmation_dialog::ConfirmationDialog; -use graphs_window::GraphsWindow; +use graphs_window::{GraphsWindow, GraphsWindowMsg}; use gtk::{ glib::{self, clone, ControlFlow}, prelude::{ @@ -46,7 +46,7 @@ const STATS_POLL_INTERVAL_MS: u64 = 250; pub struct AppModel { daemon_client: DaemonClient, - graphs_window: GraphsWindow, + graphs_window: relm4::Controller, info_page: relm4::Controller, oc_page: OcPage, @@ -212,7 +212,7 @@ impl AsyncComponent for AppModel { )); } - let graphs_window = GraphsWindow::new(); + let graphs_window = GraphsWindow::builder().launch(()).detach(); let model = AppModel { daemon_client, @@ -297,7 +297,8 @@ impl AppModel { self.thermals_page.set_stats(&stats, false); self.oc_page.set_stats(&stats, false); - self.graphs_window.set_stats(&stats); + + self.graphs_window.emit(GraphsWindowMsg::Stats(stats)); } AppMsg::ApplyChanges => { self.apply_settings(self.current_gpu_id()?, root, &sender) @@ -328,7 +329,7 @@ impl AppModel { sender.input(AppMsg::ReloadData { full: false }); } AppMsg::ShowGraphsWindow => { - self.graphs_window.show(); + self.graphs_window.emit(GraphsWindowMsg::Show); } AppMsg::DumpVBios => { self.dump_vbios(&self.current_gpu_id()?, root).await; @@ -405,13 +406,14 @@ impl AppModel { .as_ref() .map(|info| info.vram_clock_ratio) .unwrap_or(1.0); - self.graphs_window.set_vram_clock_ratio(vram_clock_ratio); + self.graphs_window + .emit(GraphsWindowMsg::VramClockRatio(vram_clock_ratio)); self.update_gpu_data(gpu_id, sender).await?; self.thermals_page.set_info(&info); - self.graphs_window.clear(); + self.graphs_window.emit(GraphsWindowMsg::Clear); Ok(()) } diff --git a/lact-gui/src/app/graphs_window/mod.rs b/lact-gui/src/app/graphs_window/mod.rs index 871583e3..3df1c097 100644 --- a/lact-gui/src/app/graphs_window/mod.rs +++ b/lact-gui/src/app/graphs_window/mod.rs @@ -1,185 +1,239 @@ pub(crate) mod plot; -use self::plot::PlotData; -use glib::Object; -use gtk::{ - glib::{self, subclass::types::ObjectSubclassIsExt}, - prelude::WidgetExt, -}; -use lact_client::schema::DeviceStats; - -const GRAPH_WIDTH_SECONDS: i64 = 60; - -glib::wrapper! { - pub struct GraphsWindow(ObjectSubclass) - @extends gtk::Box, gtk::Widget, gtk::Window, - @implements gtk::Orientable, gtk::Accessible, gtk::Buildable; +use gtk::prelude::*; +use lact_schema::DeviceStats; +use plot::{Plot, PlotData}; +use relm4::{ComponentParts, ComponentSender, RelmWidgetExt}; +use std::rc::Rc; + +pub struct GraphsWindow { + time_period_seconds_adj: gtk::Adjustment, + vram_clock_ratio: f64, } -impl GraphsWindow { - pub fn new() -> Self { - Object::builder().property("vram_clock_ratio", 1.0).build() - } - - pub fn set_stats(&self, stats: &DeviceStats) { - let imp = self.imp(); +#[derive(Debug)] +pub enum GraphsWindowMsg { + Stats(Rc), + VramClockRatio(f64), + Refresh, + Show, + Clear, +} - let mut temperature_plot = imp.temperature_plot.data_mut(); - let mut clockspeed_plot = imp.clockspeed_plot.data_mut(); - let mut power_plot = imp.power_plot.data_mut(); - let mut fan_plot = imp.fan_plot.data_mut(); +#[relm4::component(pub)] +impl relm4::Component for GraphsWindow { + type Init = (); + type Input = GraphsWindowMsg; + type Output = (); + type CommandOutput = (); + + view! { + gtk::Window { + set_default_height: 400, + set_default_width: 1200, + set_title: Some("Historical data"), + set_hide_on_close: true, + + gtk::Grid { + set_margin_all: 10, + set_row_spacing: 20, + set_column_spacing: 20, + + attach[0, 0, 1, 1]: temperature_plot = &Plot { + set_title: "Temperature", + set_hexpand: true, + set_value_suffix: "°C", + set_y_label_area_relative_size: 0.15, + #[watch] + set_time_period_seconds: model.time_period_seconds_adj.value() as i64, + }, + + attach[0, 1, 1, 1]: fan_plot = &Plot { + set_title: "Fan speed", + set_hexpand: true, + set_value_suffix: "RPM", + set_y_label_area_relative_size: 0.25, + set_secondary_y_label_area_relative_size: 0.15, + #[watch] + set_time_period_seconds: model.time_period_seconds_adj.value() as i64, + }, + + attach[1, 0, 1, 1]: clockspeed_plot = &Plot { + set_title: "Clockspeed", + set_hexpand: true, + set_value_suffix: "MHz", + set_y_label_area_relative_size: 0.3, + #[watch] + set_time_period_seconds: model.time_period_seconds_adj.value() as i64, + }, + + attach[1, 1, 1, 1]: power_plot = &Plot { + set_title: "Power usage", + set_hexpand: true, + set_value_suffix: "W", + set_y_label_area_relative_size: 0.2, + #[watch] + set_time_period_seconds: model.time_period_seconds_adj.value() as i64, + }, + + attach[1, 2, 1, 1] = >k::Box { + set_halign: gtk::Align::End, + set_spacing: 5, + + gtk::Label { + set_label: "Time period (seconds):" + }, + + gtk::SpinButton { + set_adjustment: &model.time_period_seconds_adj, + }, + }, + }, - let throttling_plots = [&mut temperature_plot, &mut clockspeed_plot, &mut power_plot]; - match &stats.throttle_info { - Some(throttle_info) => { - if throttle_info.is_empty() { - for plot in throttling_plots { - plot.push_throttling("No", false); - } - } else { - let type_text: Vec = throttle_info - .iter() - .map(|(throttle_type, details)| { - format!("{throttle_type} ({})", details.join(", ")) - }) - .collect(); - - let text = type_text.join(", "); - - for plot in throttling_plots { - plot.push_throttling(&text, true); - } - } - } - None => { - for plot in throttling_plots { - plot.push_throttling("Unknown", false); - } - } } + } - for (name, value) in &stats.temps { - temperature_plot.push_line_series(name, value.current.unwrap_or(0.0) as f64); - } + fn init( + _init: Self::Init, + root: Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let time_period_seconds_adj = gtk::Adjustment::new(60.0, 15.0, 3601.0, 1.0, 1.0, 1.0); - if let Some(average) = stats.power.average { - power_plot.push_line_series("Average", average); - } - if let Some(current) = stats.power.current { - power_plot.push_line_series("Current", current); - } - if let Some(limit) = stats.power.cap_current { - power_plot.push_line_series("Limit", limit); - } + time_period_seconds_adj.connect_value_changed(move |_| { + sender.input(GraphsWindowMsg::Refresh); + }); - if let Some(point) = stats.clockspeed.gpu_clockspeed { - clockspeed_plot.push_line_series("GPU (Avg)", point as f64); - } - if let Some(point) = stats.clockspeed.current_gfxclk { - clockspeed_plot.push_line_series("GPU (Trgt)", point as f64); - } - if let Some(point) = stats.clockspeed.vram_clockspeed { - clockspeed_plot.push_line_series("VRAM", point as f64 * self.vram_clock_ratio()); - } + let model = Self { + time_period_seconds_adj, + vram_clock_ratio: 1.0, + }; - if let Some(max_speed) = stats.fan.speed_max { - fan_plot.push_line_series("Maximum", max_speed as f64); - } - if let Some(min_speed) = stats.fan.speed_min { - fan_plot.push_line_series("Minimum", min_speed as f64); - } + let widgets = view_output!(); - if let Some(current_speed) = stats.fan.speed_current { - fan_plot.push_line_series("Current", current_speed as f64); - } + ComponentParts { model, widgets } + } - if let Some(pwm) = stats.fan.pwm_current { - fan_plot - .push_secondary_line_series("Percentage", (pwm as f64 / u8::MAX as f64) * 100.0); - } + fn update_with_view( + &mut self, + widgets: &mut Self::Widgets, + msg: Self::Input, + sender: ComponentSender, + root: &Self::Root, + ) { + match msg { + GraphsWindowMsg::Refresh => {} + GraphsWindowMsg::Show => { + root.show(); + } + GraphsWindowMsg::VramClockRatio(ratio) => { + self.vram_clock_ratio = ratio; + } + GraphsWindowMsg::Stats(stats) => { + let mut temperature_plot = widgets.temperature_plot.data_mut(); + let mut clockspeed_plot = widgets.clockspeed_plot.data_mut(); + let mut power_plot = widgets.power_plot.data_mut(); + let mut fan_plot = widgets.fan_plot.data_mut(); + + let throttling_plots = + [&mut temperature_plot, &mut clockspeed_plot, &mut power_plot]; + match &stats.throttle_info { + Some(throttle_info) => { + if throttle_info.is_empty() { + for plot in throttling_plots { + plot.push_throttling("No", false); + } + } else { + let type_text: Vec = throttle_info + .iter() + .map(|(throttle_type, details)| { + format!("{throttle_type} ({})", details.join(", ")) + }) + .collect(); + + let text = type_text.join(", "); + + for plot in throttling_plots { + plot.push_throttling(&text, true); + } + } + } + None => { + for plot in throttling_plots { + plot.push_throttling("Unknown", false); + } + } + } - temperature_plot.trim_data(GRAPH_WIDTH_SECONDS); - clockspeed_plot.trim_data(GRAPH_WIDTH_SECONDS); - power_plot.trim_data(GRAPH_WIDTH_SECONDS); - fan_plot.trim_data(GRAPH_WIDTH_SECONDS); + for (name, value) in &stats.temps { + temperature_plot.push_line_series(name, value.current.unwrap_or(0.0) as f64); + } - imp.temperature_plot.queue_draw(); - imp.clockspeed_plot.queue_draw(); - imp.power_plot.queue_draw(); - imp.fan_plot.queue_draw(); - } + if let Some(average) = stats.power.average { + power_plot.push_line_series("Average", average); + } + if let Some(current) = stats.power.current { + power_plot.push_line_series("Current", current); + } + if let Some(limit) = stats.power.cap_current { + power_plot.push_line_series("Limit", limit); + } - pub fn clear(&self) { - let imp = self.imp(); - *imp.temperature_plot.data_mut() = PlotData::default(); - *imp.clockspeed_plot.data_mut() = PlotData::default(); - *imp.power_plot.data_mut() = PlotData::default(); - *imp.fan_plot.data_mut() = PlotData::default(); - - imp.temperature_plot.queue_draw(); - imp.clockspeed_plot.queue_draw(); - imp.power_plot.queue_draw(); - imp.fan_plot.queue_draw(); - } -} + if let Some(point) = stats.clockspeed.gpu_clockspeed { + clockspeed_plot.push_line_series("GPU (Avg)", point as f64); + } + if let Some(point) = stats.clockspeed.current_gfxclk { + clockspeed_plot.push_line_series("GPU (Trgt)", point as f64); + } + if let Some(point) = stats.clockspeed.vram_clockspeed { + clockspeed_plot.push_line_series("VRAM", point as f64 * self.vram_clock_ratio); + } -impl Default for GraphsWindow { - fn default() -> Self { - Self::new() - } -} + if let Some(max_speed) = stats.fan.speed_max { + fan_plot.push_line_series("Maximum", max_speed as f64); + } + if let Some(min_speed) = stats.fan.speed_min { + fan_plot.push_line_series("Minimum", min_speed as f64); + } -mod imp { - use super::plot::Plot; - use gtk::{ - glib::{self, subclass::InitializingObject, Properties}, - prelude::*, - subclass::{ - prelude::*, - widget::{CompositeTemplateClass, WidgetImpl}, - }, - CompositeTemplate, - }; - use std::cell::Cell; - - #[derive(CompositeTemplate, Default, Properties)] - #[properties(wrapper_type = super::GraphsWindow)] - #[template(file = "ui/graphs_window.blp")] - pub struct GraphsWindow { - #[template_child] - pub(super) temperature_plot: TemplateChild, - #[template_child] - pub(super) clockspeed_plot: TemplateChild, - #[template_child] - pub(super) power_plot: TemplateChild, - #[template_child] - pub(super) fan_plot: TemplateChild, - - #[property(get, set)] - pub vram_clock_ratio: Cell, - } + if let Some(current_speed) = stats.fan.speed_current { + fan_plot.push_line_series("Current", current_speed as f64); + } - #[glib::object_subclass] - impl ObjectSubclass for GraphsWindow { - const NAME: &'static str = "GraphsWindow"; - type Type = super::GraphsWindow; - type ParentType = gtk::Window; + if let Some(pwm) = stats.fan.pwm_current { + fan_plot.push_secondary_line_series( + "Percentage", + (pwm as f64 / u8::MAX as f64) * 100.0, + ); + } - fn class_init(class: &mut Self::Class) { - Plot::ensure_type(); + let time_period_seconds = self.time_period_seconds_adj.value() as i64; + temperature_plot.trim_data(time_period_seconds); + clockspeed_plot.trim_data(time_period_seconds); + power_plot.trim_data(time_period_seconds); + fan_plot.trim_data(time_period_seconds); - class.bind_template(); - } + Self::queue_plots_draw(widgets); + } + GraphsWindowMsg::Clear => { + *widgets.temperature_plot.data_mut() = PlotData::default(); + *widgets.clockspeed_plot.data_mut() = PlotData::default(); + *widgets.power_plot.data_mut() = PlotData::default(); + *widgets.fan_plot.data_mut() = PlotData::default(); - fn instance_init(obj: &InitializingObject) { - obj.init_template(); + Self::queue_plots_draw(widgets); + } } - } - #[glib::derived_properties] - impl ObjectImpl for GraphsWindow {} + self.update_view(widgets, sender); + } +} - impl WidgetImpl for GraphsWindow {} - impl WindowImpl for GraphsWindow {} - impl ApplicationWindowImpl for GraphsWindow {} +impl GraphsWindow { + fn queue_plots_draw(widgets: &::Widgets) { + widgets.temperature_plot.queue_draw(); + widgets.clockspeed_plot.queue_draw(); + widgets.power_plot.queue_draw(); + widgets.fan_plot.queue_draw(); + } } diff --git a/lact-gui/src/app/graphs_window/plot/imp.rs b/lact-gui/src/app/graphs_window/plot/imp.rs index adf17d6e..18b6ebc6 100644 --- a/lact-gui/src/app/graphs_window/plot/imp.rs +++ b/lact-gui/src/app/graphs_window/plot/imp.rs @@ -25,6 +25,8 @@ pub struct Plot { pub(super) data: RefCell, pub(super) dirty: Cell, render_thread: RenderThread, + #[property(get, set)] + time_period_seconds: Cell, } #[glib::object_subclass] @@ -74,6 +76,7 @@ impl WidgetImpl for Plot { .secondary_y_label_area_relative_size .get(), supersample_factor: 4, + time_period_seconds: self.time_period_seconds.get(), }); } diff --git a/lact-gui/src/app/graphs_window/plot/mod.rs b/lact-gui/src/app/graphs_window/plot/mod.rs index 35843af1..4fb539b8 100644 --- a/lact-gui/src/app/graphs_window/plot/mod.rs +++ b/lact-gui/src/app/graphs_window/plot/mod.rs @@ -7,13 +7,19 @@ use std::cell::RefMut; pub use imp::PlotData; -use gtk::glib::{self, subclass::types::ObjectSubclassIsExt}; +use gtk::glib::{self, subclass::types::ObjectSubclassIsExt, Object}; glib::wrapper! { pub struct Plot(ObjectSubclass) @extends gtk::Widget; } +impl Default for Plot { + fn default() -> Self { + Object::builder().build() + } +} + impl Plot { pub fn data_mut(&self) -> RefMut<'_, PlotData> { self.imp().dirty.set(true); diff --git a/lact-gui/src/app/graphs_window/plot/render_thread.rs b/lact-gui/src/app/graphs_window/plot/render_thread.rs index 99ce3e21..b776015b 100644 --- a/lact-gui/src/app/graphs_window/plot/render_thread.rs +++ b/lact-gui/src/app/graphs_window/plot/render_thread.rs @@ -35,6 +35,8 @@ pub struct RenderRequest { pub height: u32, pub supersample_factor: u32, + + pub time_period_seconds: i64, } #[derive(Default)] @@ -259,11 +261,11 @@ impl RenderRequest { ("sans-serif", RelativeSize::Smaller(0.08)), ) .build_cartesian_2d( - start_date..max(end_date, start_date + 60 * 1000), + start_date..max(end_date, start_date + self.time_period_seconds * 1000), 0f64..maximum_value, )? .set_secondary_coord( - start_date..max(end_date, start_date + 60 * 1000), + start_date..max(end_date, start_date + self.time_period_seconds * 1000), 0.0..100.0, ); diff --git a/lact-gui/ui/graphs_window.blp b/lact-gui/ui/graphs_window.blp deleted file mode 100644 index 3afec8d2..00000000 --- a/lact-gui/ui/graphs_window.blp +++ /dev/null @@ -1,67 +0,0 @@ -using Gtk 4.0; - -template $GraphsWindow: Window { - default-height: 400; - default-width: 1200; - title: "Historical data"; - hide-on-close: true; - - Grid { - margin-top: 10; - margin-bottom: 10; - margin-start: 10; - margin-end: 10; - row-spacing: 20; - column-spacing: 20; - - $Plot temperature_plot { - title: "Temperature"; - hexpand: true; - value-suffix: "°C"; - y-label-area-relative-size: 0.15; - - layout { - column: 0; - row: 0; - } - } - - $Plot fan_plot { - title: "Fan speed"; - hexpand: true; - value-suffix: "RPM"; - secondary-value-suffix: "%"; - y-label-area-relative-size: 0.25; - secondary-y-label-area-relative-size: 0.15; - - layout { - column: 0; - row: 1; - } - } - - $Plot clockspeed_plot { - title: "Clockspeed"; - hexpand: true; - value-suffix: "MHz"; - y-label-area-relative-size: 0.3; - - layout { - column: 1; - row: 0; - } - } - - $Plot power_plot { - title: "Power usage"; - hexpand: true; - value-suffix: "W"; - y-label-area-relative-size: 0.2; - - layout { - column: 1; - row: 1; - } - } - } -}