mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
feat: SoftwarePage in blueprint
feat: PageSection
This commit is contained in:
72
lact-gui/src/app/info_row.rs
Normal file
72
lact-gui/src/app/info_row.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
use gtk::glib::{self, Object};
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct InfoRow(ObjectSubclass<imp::InfoRow>)
|
||||
@extends gtk::Box, gtk::Widget,
|
||||
@implements gtk::Orientable, gtk::Accessible, gtk::Buildable;
|
||||
}
|
||||
|
||||
impl InfoRow {
|
||||
pub fn new(name: &str, value: &str) -> Self {
|
||||
Object::builder()
|
||||
.property("name", name)
|
||||
.property("value", value)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use glib::Properties;
|
||||
use gtk::{
|
||||
glib::{self, subclass::InitializingObject},
|
||||
pango::AttrList,
|
||||
prelude::*,
|
||||
subclass::{
|
||||
prelude::*,
|
||||
widget::{CompositeTemplateClass, WidgetImpl},
|
||||
},
|
||||
CompositeTemplate, Label, TemplateChild,
|
||||
};
|
||||
use std::{cell::RefCell, str::FromStr};
|
||||
|
||||
#[derive(CompositeTemplate, Default, Properties)]
|
||||
#[properties(wrapper_type = super::InfoRow)]
|
||||
#[template(file = "ui/info_row.blp")]
|
||||
pub struct InfoRow {
|
||||
#[property(get, set)]
|
||||
name: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
value: RefCell<String>,
|
||||
|
||||
#[template_child]
|
||||
value_label: TemplateChild<Label>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for InfoRow {
|
||||
const NAME: &'static str = "InfoRow";
|
||||
type Type = super::InfoRow;
|
||||
type ParentType = gtk::Box;
|
||||
|
||||
fn class_init(class: &mut Self::Class) {
|
||||
class.bind_template();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
#[glib::derived_properties]
|
||||
impl ObjectImpl for InfoRow {
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
|
||||
let attr_list = AttrList::from_str("0 -1 weight bold").unwrap();
|
||||
self.value_label.set_attributes(Some(&attr_list));
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetImpl for InfoRow {}
|
||||
impl BoxImpl for InfoRow {}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
mod apply_revealer;
|
||||
mod header;
|
||||
mod info_row;
|
||||
mod page_section;
|
||||
mod root_stack;
|
||||
|
||||
use crate::{APP_ID, GUI_VERSION};
|
||||
|
||||
70
lact-gui/src/app/page_section.rs
Normal file
70
lact-gui/src/app/page_section.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
use gtk::glib::{self, Object};
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct PageSection(ObjectSubclass<imp::PageSection>)
|
||||
@extends gtk::Box, gtk::Widget,
|
||||
@implements gtk::Orientable, gtk::Accessible, gtk::Buildable;
|
||||
}
|
||||
|
||||
impl PageSection {
|
||||
pub fn new(name: &str) -> Self {
|
||||
Object::builder().property("name", name).build()
|
||||
}
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use glib::Properties;
|
||||
use gtk::{
|
||||
glib::{self, subclass::InitializingObject},
|
||||
prelude::*,
|
||||
subclass::{
|
||||
prelude::*,
|
||||
widget::{CompositeTemplateClass, WidgetImpl},
|
||||
},
|
||||
CompositeTemplate, Label, TemplateChild,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
|
||||
#[derive(CompositeTemplate, Default, Properties)]
|
||||
#[properties(wrapper_type = super::PageSection)]
|
||||
#[template(file = "ui/page_section.blp")]
|
||||
pub struct PageSection {
|
||||
#[template_child]
|
||||
section_label: TemplateChild<Label>,
|
||||
|
||||
#[property(get, set)]
|
||||
name: RefCell<String>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for PageSection {
|
||||
const NAME: &'static str = "PageSection";
|
||||
type Type = super::PageSection;
|
||||
type ParentType = gtk::Box;
|
||||
|
||||
fn class_init(class: &mut Self::Class) {
|
||||
class.bind_template();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
#[glib::derived_properties]
|
||||
impl ObjectImpl for PageSection {
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
let obj = self.obj();
|
||||
|
||||
obj.bind_property("name", &self.section_label.get(), "label")
|
||||
.transform_to(|_, value: String| {
|
||||
Some(format!("<span font_desc='13'><b>{value}</b></span>"))
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetImpl for PageSection {}
|
||||
impl BoxImpl for PageSection {}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
mod vulkan_info;
|
||||
|
||||
use super::{label_row, values_grid};
|
||||
use crate::app::page_section::PageSection;
|
||||
use gtk::prelude::*;
|
||||
use gtk::*;
|
||||
use lact_client::schema::{DeviceInfo, DeviceStats};
|
||||
use vulkan_info::VulkanInfoFrame;
|
||||
|
||||
use super::{label_row, section_box, values_grid};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InformationPage {
|
||||
pub container: ScrolledWindow,
|
||||
@@ -34,7 +34,7 @@ impl InformationPage {
|
||||
pub fn new() -> Self {
|
||||
let vbox = Box::new(Orientation::Vertical, 15);
|
||||
|
||||
let info_container = section_box("Hardware Information");
|
||||
let info_container = PageSection::new("Hardware Information");
|
||||
|
||||
let values_grid = values_grid();
|
||||
|
||||
@@ -69,7 +69,7 @@ impl InformationPage {
|
||||
info_container.append(&values_grid);
|
||||
vbox.append(&info_container);
|
||||
|
||||
let vulkan_container = section_box("Vulkan Information");
|
||||
let vulkan_container = PageSection::new("Vulkan Information");
|
||||
|
||||
let vulkan_info_frame = VulkanInfoFrame::new();
|
||||
vulkan_container.append(&vulkan_info_frame.container);
|
||||
|
||||
@@ -3,13 +3,9 @@ mod oc_page;
|
||||
mod software_page;
|
||||
mod thermals_page;
|
||||
|
||||
use gtk::{
|
||||
prelude::IsA,
|
||||
traits::{BoxExt, GridExt},
|
||||
*,
|
||||
};
|
||||
use gtk::{prelude::IsA, traits::GridExt, *};
|
||||
|
||||
use self::software_page::software_page;
|
||||
use self::software_page::SoftwarePage;
|
||||
use info_page::InformationPage;
|
||||
use lact_client::schema::SystemInfo;
|
||||
use oc_page::OcPage;
|
||||
@@ -44,7 +40,7 @@ impl RootStack {
|
||||
|
||||
container.add_titled(&thermals_page.container, Some("thermals_page"), "Thermals");
|
||||
|
||||
let software_page = software_page(system_info, embedded_daemon);
|
||||
let software_page = SoftwarePage::new(system_info, embedded_daemon);
|
||||
container.add_titled(&software_page, Some("software_page"), "Software");
|
||||
|
||||
Self {
|
||||
@@ -80,26 +76,6 @@ fn label_row(title: &str, parent: &Grid, row: i32, column_offset: i32, selectabl
|
||||
value_label
|
||||
}
|
||||
|
||||
fn section_box(title: &str) -> Box {
|
||||
let container = Box::builder()
|
||||
.orientation(Orientation::Vertical)
|
||||
.spacing(5)
|
||||
.margin_start(5)
|
||||
.margin_end(5)
|
||||
.build();
|
||||
|
||||
let label = Label::builder()
|
||||
.use_markup(true)
|
||||
.label(format!("<span font_desc='13'><b>{title}</b></span>"))
|
||||
.halign(Align::Start)
|
||||
.margin_top(5)
|
||||
.margin_bottom(5)
|
||||
.build();
|
||||
|
||||
container.append(&label);
|
||||
container
|
||||
}
|
||||
|
||||
fn values_grid() -> Grid {
|
||||
Grid::builder()
|
||||
.margin_start(10)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::app::root_stack::section_box;
|
||||
use crate::app::page_section::PageSection;
|
||||
use glib::clone;
|
||||
use gtk::prelude::*;
|
||||
use gtk::*;
|
||||
@@ -14,7 +14,7 @@ const WARNING_TEXT: &str = "Warning: changing these values may lead to system in
|
||||
// The AtomicBool stores if the value was changed
|
||||
#[derive(Clone)]
|
||||
pub struct ClocksFrame {
|
||||
pub container: Box,
|
||||
pub container: PageSection,
|
||||
tweaking_grid: Grid,
|
||||
modes_switcher_box: Box,
|
||||
basic_togglebutton: ToggleButton,
|
||||
@@ -34,7 +34,7 @@ pub struct ClocksFrame {
|
||||
|
||||
impl ClocksFrame {
|
||||
pub fn new() -> Self {
|
||||
let container = section_box("Clockspeed and voltage");
|
||||
let container = PageSection::new("Clockspeed and voltage");
|
||||
|
||||
let warning_label = Label::builder()
|
||||
.label(WARNING_TEXT)
|
||||
|
||||
@@ -38,8 +38,6 @@ impl OcPage {
|
||||
let vbox = Box::builder()
|
||||
.orientation(Orientation::Vertical)
|
||||
.spacing(15)
|
||||
.margin_start(5)
|
||||
.margin_end(5)
|
||||
.build();
|
||||
|
||||
let mut enable_overclocking_button = None;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::app::root_stack::section_box;
|
||||
use crate::app::page_section::PageSection;
|
||||
use glib::clone;
|
||||
use gtk::prelude::*;
|
||||
use gtk::*;
|
||||
@@ -9,7 +9,7 @@ use std::{cell::RefCell, rc::Rc, str::FromStr};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PerformanceFrame {
|
||||
pub container: Box,
|
||||
pub container: PageSection,
|
||||
level_drop_down: DropDown,
|
||||
mode_drop_down: DropDown,
|
||||
description_label: Label,
|
||||
@@ -20,7 +20,7 @@ pub struct PerformanceFrame {
|
||||
|
||||
impl PerformanceFrame {
|
||||
pub fn new() -> Self {
|
||||
let container = section_box("Performance");
|
||||
let container = PageSection::new("Performance");
|
||||
|
||||
let levels_model: StringList = ["Automatic", "Highest Clocks", "Lowest Clocks", "Manual"]
|
||||
.into_iter()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::oc_adjustment::OcAdjustment;
|
||||
use crate::app::root_stack::section_box;
|
||||
use crate::app::page_section::PageSection;
|
||||
use gtk::*;
|
||||
use gtk::{glib::clone, prelude::*};
|
||||
use std::{cell::Cell, rc::Rc};
|
||||
@@ -7,14 +7,14 @@ use tracing::error;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PowerCapFrame {
|
||||
pub container: Box,
|
||||
pub container: PageSection,
|
||||
default_cap: Rc<Cell<Option<f64>>>,
|
||||
adjustment: OcAdjustment,
|
||||
}
|
||||
|
||||
impl PowerCapFrame {
|
||||
pub fn new() -> Self {
|
||||
let container = section_box("Power Usage Limit");
|
||||
let container = PageSection::new("Power Usage Limit");
|
||||
let default_cap = Rc::new(Cell::new(None));
|
||||
|
||||
let value_suffix = "W";
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::app::root_stack::{label_row, section_box};
|
||||
use crate::app::{page_section::PageSection, root_stack::label_row};
|
||||
use gtk::prelude::*;
|
||||
use gtk::*;
|
||||
use lact_client::schema::{ClockspeedStats, DeviceStats, PowerStats, VoltageStats, VramStats};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct StatsFrame {
|
||||
pub container: Box,
|
||||
pub container: PageSection,
|
||||
vram_usage_bar: LevelBar,
|
||||
vram_usage_label: Label,
|
||||
gpu_clock_label: Label,
|
||||
@@ -18,7 +18,7 @@ pub struct StatsFrame {
|
||||
|
||||
impl StatsFrame {
|
||||
pub fn new() -> Self {
|
||||
let container = section_box("Statistics");
|
||||
let container = PageSection::new("Statistics");
|
||||
|
||||
let vram_usage_hbox = Box::new(Orientation::Horizontal, 5);
|
||||
|
||||
|
||||
@@ -1,92 +1,83 @@
|
||||
use crate::GUI_VERSION;
|
||||
use gtk::prelude::*;
|
||||
use gtk::*;
|
||||
use gtk::glib::{self, Object};
|
||||
use lact_client::schema::SystemInfo;
|
||||
|
||||
pub fn software_page(system_info: SystemInfo, embedded: bool) -> Grid {
|
||||
let container = Grid::new();
|
||||
|
||||
container.set_margin_start(5);
|
||||
container.set_margin_end(5);
|
||||
container.set_margin_bottom(5);
|
||||
container.set_margin_top(5);
|
||||
|
||||
container.set_column_spacing(5);
|
||||
|
||||
container.attach(
|
||||
&{
|
||||
let label = Label::new(None);
|
||||
label.set_markup("LACT Daemon:");
|
||||
label.set_halign(Align::End);
|
||||
label.set_hexpand(true);
|
||||
label
|
||||
},
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
);
|
||||
let mut daemon_version = format!("{}-{}", system_info.version, system_info.profile);
|
||||
if embedded {
|
||||
daemon_version.push_str("-embedded");
|
||||
}
|
||||
let daemon_version_label = Label::builder()
|
||||
.use_markup(true)
|
||||
.label(format!("<b>{daemon_version}</b>"))
|
||||
.hexpand(true)
|
||||
.halign(Align::Start)
|
||||
.build();
|
||||
|
||||
container.attach(&daemon_version_label, 1, 0, 1, 1);
|
||||
|
||||
container.attach(
|
||||
&{
|
||||
let label = Label::new(None);
|
||||
label.set_markup("LACT GUI:");
|
||||
label.set_halign(Align::End);
|
||||
label.set_hexpand(true);
|
||||
label
|
||||
},
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
);
|
||||
|
||||
let gui_profile = if cfg!(debug_assertions) {
|
||||
"debug"
|
||||
} else {
|
||||
"release"
|
||||
};
|
||||
let gui_version = format!("{GUI_VERSION}-{gui_profile}");
|
||||
|
||||
let gui_version_label = Label::builder()
|
||||
.use_markup(true)
|
||||
.label(format!("<b>{gui_version}</b>"))
|
||||
.hexpand(true)
|
||||
.halign(Align::Start)
|
||||
.build();
|
||||
|
||||
container.attach(&gui_version_label, 1, 1, 1, 1);
|
||||
|
||||
container.attach(
|
||||
&Label::builder()
|
||||
.label("Kernel version:")
|
||||
.halign(Align::End)
|
||||
.hexpand(true)
|
||||
.build(),
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
);
|
||||
let kernel_version_label = Label::builder()
|
||||
.use_markup(true)
|
||||
.label(format!("<b>{}</b>", system_info.kernel_version))
|
||||
.hexpand(true)
|
||||
.halign(Align::Start)
|
||||
.build();
|
||||
container.attach(&kernel_version_label, 1, 2, 1, 1);
|
||||
|
||||
container
|
||||
glib::wrapper! {
|
||||
pub struct SoftwarePage(ObjectSubclass<imp::SoftwarePage>)
|
||||
@extends gtk::Box, gtk::Widget,
|
||||
@implements gtk::Orientable, gtk::Accessible, gtk::Buildable;
|
||||
}
|
||||
|
||||
impl SoftwarePage {
|
||||
pub fn new(system_info: SystemInfo, embedded: bool) -> Self {
|
||||
let mut daemon_version = format!("{}-{}", system_info.version, system_info.profile);
|
||||
if embedded {
|
||||
daemon_version.push_str("-embedded");
|
||||
}
|
||||
|
||||
let gui_profile = if cfg!(debug_assertions) {
|
||||
"debug"
|
||||
} else {
|
||||
"release"
|
||||
};
|
||||
let gui_version = format!("{GUI_VERSION}-{gui_profile}");
|
||||
|
||||
Object::builder()
|
||||
.property("daemon-version", daemon_version)
|
||||
.property("gui-version", gui_version)
|
||||
.property("kernel-version", system_info.kernel_version)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
mod imp {
|
||||
#![allow(clippy::enum_variant_names)]
|
||||
use crate::app::{info_row::InfoRow, page_section::PageSection};
|
||||
use glib::Properties;
|
||||
use gtk::{
|
||||
glib::{self, subclass::InitializingObject},
|
||||
prelude::*,
|
||||
subclass::{
|
||||
prelude::*,
|
||||
widget::{CompositeTemplateClass, WidgetImpl},
|
||||
},
|
||||
CompositeTemplate,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
|
||||
#[derive(CompositeTemplate, Default, Properties)]
|
||||
#[properties(wrapper_type = super::SoftwarePage)]
|
||||
#[template(file = "ui/software_page.blp")]
|
||||
pub struct SoftwarePage {
|
||||
#[property(get, set)]
|
||||
daemon_version: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
gui_version: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
kernel_version: RefCell<String>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for SoftwarePage {
|
||||
const NAME: &'static str = "SoftwarePage";
|
||||
type Type = super::SoftwarePage;
|
||||
type ParentType = gtk::Box;
|
||||
|
||||
fn class_init(class: &mut Self::Class) {
|
||||
InfoRow::ensure_type();
|
||||
PageSection::ensure_type();
|
||||
|
||||
class.bind_template();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
#[glib::derived_properties]
|
||||
impl ObjectImpl for SoftwarePage {}
|
||||
|
||||
impl WidgetImpl for SoftwarePage {}
|
||||
impl BoxImpl for SoftwarePage {}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,11 @@ use gtk::prelude::*;
|
||||
use gtk::*;
|
||||
use lact_client::schema::{default_fan_curve, DeviceStats, FanControlMode, FanCurveMap};
|
||||
|
||||
use crate::app::page_section::PageSection;
|
||||
|
||||
use self::fan_curve_frame::FanCurveFrame;
|
||||
|
||||
use super::{label_row, section_box, values_grid};
|
||||
use super::{label_row, values_grid};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ThermalsSettings {
|
||||
@@ -32,7 +34,7 @@ impl ThermalsPage {
|
||||
pub fn new() -> Self {
|
||||
let container = Box::new(Orientation::Vertical, 15);
|
||||
|
||||
let stats_section = section_box("Statistics");
|
||||
let stats_section = PageSection::new("Statistics");
|
||||
let stats_grid = values_grid();
|
||||
|
||||
let temperatures_label = label_row("Temperatures:", &stats_grid, 0, 0, false);
|
||||
@@ -51,7 +53,7 @@ impl ThermalsPage {
|
||||
.build();
|
||||
let fan_static_speed_adjustment = static_speed_adj(&fan_static_speed_frame);
|
||||
|
||||
let fan_control_section = section_box("Fan control");
|
||||
let fan_control_section = PageSection::new("Fan control");
|
||||
|
||||
let fan_control_mode_stack = Stack::builder().build();
|
||||
let fan_control_mode_stack_switcher = StackSwitcher::builder()
|
||||
|
||||
@@ -8,7 +8,7 @@ use tracing::{error, info, metadata::LevelFilter};
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
const GUI_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
const APP_ID: &str = "io.github.lact-linux1";
|
||||
const APP_ID: &str = "io.github.lact-linux";
|
||||
|
||||
pub fn run(args: GuiArgs) -> anyhow::Result<()> {
|
||||
let env_filter = EnvFilter::builder()
|
||||
|
||||
21
lact-gui/ui/info_row.blp
Normal file
21
lact-gui/ui/info_row.blp
Normal file
@@ -0,0 +1,21 @@
|
||||
using Gtk 4.0;
|
||||
using Pango 1.0;
|
||||
|
||||
template $InfoRow: Box {
|
||||
orientation: horizontal;
|
||||
hexpand: true;
|
||||
margin-start: 10;
|
||||
margin-end: 10;
|
||||
|
||||
Label {
|
||||
label: bind template.name;
|
||||
halign: start;
|
||||
hexpand: true;
|
||||
}
|
||||
|
||||
Label value_label {
|
||||
label: bind template.value;
|
||||
halign: end;
|
||||
selectable: true;
|
||||
}
|
||||
}
|
||||
15
lact-gui/ui/page_section.blp
Normal file
15
lact-gui/ui/page_section.blp
Normal file
@@ -0,0 +1,15 @@
|
||||
using Gtk 4.0;
|
||||
|
||||
template $PageSection: Box {
|
||||
orientation: vertical;
|
||||
spacing: 5;
|
||||
margin-start: 5;
|
||||
margin-end: 5;
|
||||
|
||||
Label section_label {
|
||||
halign: start;
|
||||
use-markup: true;
|
||||
margin-top: 5;
|
||||
margin-bottom: 5;
|
||||
}
|
||||
}
|
||||
25
lact-gui/ui/software_page.blp
Normal file
25
lact-gui/ui/software_page.blp
Normal file
@@ -0,0 +1,25 @@
|
||||
using Gtk 4.0;
|
||||
|
||||
template $SoftwarePage: Box {
|
||||
orientation: vertical;
|
||||
spacing: 10;
|
||||
margin-start: 5;
|
||||
margin-end: 5;
|
||||
margin-top: 5;
|
||||
margin-bottom: 5;
|
||||
|
||||
$InfoRow {
|
||||
name: "LACT Daemon:";
|
||||
value: bind template.daemon_version;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "LACT GUI:";
|
||||
value: bind template.gui_version;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "Kernel Version:";
|
||||
value: bind template.kernel_version;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user