Fix clippy
This commit is contained in:
parent
bcf2b9e5f9
commit
8d8f4932c1
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -152,6 +152,7 @@ dependencies = [
|
||||
"egui_glium",
|
||||
"egui_glow",
|
||||
"egui_vulkano",
|
||||
"emath 0.18.0",
|
||||
"epaint 0.18.1",
|
||||
"epi",
|
||||
"glium 0.32.1",
|
||||
|
@ -18,18 +18,170 @@ pub enum PortsError {
|
||||
Serialize(#[from] ron::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
pub enum OutputType {
|
||||
Reserved,
|
||||
#[serde(rename = "v")]
|
||||
Vga,
|
||||
#[serde(rename = "m")]
|
||||
MiniDvi,
|
||||
#[serde(rename = "h")]
|
||||
Hdmi,
|
||||
#[serde(rename = "a")]
|
||||
Audio,
|
||||
#[serde(rename = "o")]
|
||||
OpticalAudio,
|
||||
#[serde(rename = "d")]
|
||||
Dvi,
|
||||
#[serde(rename = "t")]
|
||||
Thunderbolt,
|
||||
#[serde(rename = "D")]
|
||||
DisplayPort,
|
||||
#[serde(rename = "M")]
|
||||
MiniDisplayPort,
|
||||
#[serde(rename = "f")]
|
||||
FireWire400,
|
||||
#[serde(rename = "p")]
|
||||
Ps2,
|
||||
#[serde(rename = "s")]
|
||||
Sata,
|
||||
#[serde(rename = "e")]
|
||||
ESata,
|
||||
#[serde(rename = "E")]
|
||||
Ethernet,
|
||||
#[serde(rename = "F")]
|
||||
FireWire800,
|
||||
#[serde(rename = "1")]
|
||||
UsbTypeA,
|
||||
#[serde(rename = "2")]
|
||||
UsbTypeB,
|
||||
#[serde(rename = "3")]
|
||||
UsbTypeC,
|
||||
#[serde(rename = "4")]
|
||||
MicroUsb,
|
||||
#[serde(rename = "5")]
|
||||
MimiUsb,
|
||||
}
|
||||
|
||||
impl OutputType {
|
||||
pub fn to_coords(&self) -> (u32, u32) {
|
||||
match self {
|
||||
OutputType::Reserved => (0, 0),
|
||||
//
|
||||
OutputType::Vga => (0, 0),
|
||||
OutputType::MiniDvi => (80, 0),
|
||||
OutputType::Hdmi => (160, 0),
|
||||
OutputType::Audio => (240, 0),
|
||||
OutputType::OpticalAudio => (320, 0),
|
||||
//
|
||||
OutputType::Dvi => (0, 80),
|
||||
OutputType::Thunderbolt => (80, 80),
|
||||
OutputType::DisplayPort => (160, 80),
|
||||
OutputType::MiniDisplayPort => (240, 80),
|
||||
OutputType::FireWire400 => (320, 80),
|
||||
//
|
||||
OutputType::Ps2 => (0, 160),
|
||||
OutputType::Sata => (80, 160),
|
||||
OutputType::ESata => (160, 160),
|
||||
OutputType::Ethernet => (240, 160),
|
||||
OutputType::FireWire800 => (320, 160),
|
||||
//
|
||||
OutputType::UsbTypeA => (0, 240),
|
||||
OutputType::UsbTypeB => (80, 240),
|
||||
OutputType::UsbTypeC => (160, 240),
|
||||
OutputType::MicroUsb => (240, 240),
|
||||
OutputType::MimiUsb => (320, 240),
|
||||
}
|
||||
}
|
||||
pub fn name(&self) -> &str {
|
||||
match self {
|
||||
OutputType::Reserved => "-----",
|
||||
//
|
||||
OutputType::Vga => "Vga",
|
||||
OutputType::MiniDvi => "MiniDvi",
|
||||
OutputType::Hdmi => "Hdmi",
|
||||
OutputType::Audio => "Audio",
|
||||
OutputType::OpticalAudio => "OptimalAudio",
|
||||
//
|
||||
OutputType::Dvi => "Dvi",
|
||||
OutputType::Thunderbolt => "Thunderbolt",
|
||||
OutputType::DisplayPort => "DisplayPort",
|
||||
OutputType::MiniDisplayPort => "MiniDisplayPort",
|
||||
OutputType::FireWire400 => "FireWire400",
|
||||
//
|
||||
OutputType::Ps2 => "Ps2",
|
||||
OutputType::Sata => "Sata",
|
||||
OutputType::ESata => "ESata",
|
||||
OutputType::Ethernet => "Ethernet",
|
||||
OutputType::FireWire800 => "FireWire800",
|
||||
//
|
||||
OutputType::UsbTypeA => "UsbTypeA",
|
||||
OutputType::UsbTypeB => "UsbTypeB",
|
||||
OutputType::UsbTypeC => "UsbTypeC",
|
||||
OutputType::MicroUsb => "MicroUsb",
|
||||
OutputType::MimiUsb => "MimiUsb",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_str(s: &str) -> Option<Self> {
|
||||
Some(match s {
|
||||
"DP" => Self::DisplayPort,
|
||||
"eDP" => Self::MiniDisplayPort,
|
||||
"HDMI" => Self::Hdmi,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn all() -> [OutputType; 20] {
|
||||
[
|
||||
OutputType::Vga,
|
||||
OutputType::MiniDvi,
|
||||
OutputType::Hdmi,
|
||||
OutputType::Audio,
|
||||
OutputType::OpticalAudio,
|
||||
OutputType::Dvi,
|
||||
OutputType::Thunderbolt,
|
||||
OutputType::DisplayPort,
|
||||
OutputType::MiniDisplayPort,
|
||||
OutputType::FireWire400,
|
||||
OutputType::Ps2,
|
||||
OutputType::Sata,
|
||||
OutputType::ESata,
|
||||
OutputType::Ethernet,
|
||||
OutputType::FireWire800,
|
||||
OutputType::UsbTypeA,
|
||||
OutputType::UsbTypeB,
|
||||
OutputType::UsbTypeC,
|
||||
OutputType::MicroUsb,
|
||||
OutputType::MimiUsb,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
pub struct Output {
|
||||
#[serde(rename = "c")]
|
||||
pub card: String,
|
||||
#[serde(rename = "t")]
|
||||
pub port_type: String,
|
||||
#[serde(rename = "T")]
|
||||
pub ty: Option<OutputType>,
|
||||
#[serde(rename = "m")]
|
||||
pub port_name: Option<String>,
|
||||
#[serde(rename = "n")]
|
||||
pub port_number: u8,
|
||||
#[serde(rename = "s")]
|
||||
pub status: Status,
|
||||
#[serde(rename = "M")]
|
||||
pub modes: Vec<OutputMode>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
pub struct OutputMode {
|
||||
#[serde(rename = "w")]
|
||||
pub width: u16,
|
||||
#[serde(rename = "h")]
|
||||
pub height: u16,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
@ -65,6 +65,7 @@ parking_lot = { version = "0.12" }
|
||||
nix = { version = "0.25" }
|
||||
|
||||
image = { version = "0.24.2" }
|
||||
emath = { version = "0.18" }
|
||||
|
||||
[dev-dependencies]
|
||||
amdgpu = { path = "../amdgpu", version = "1.0", features = ["gui-helper"] }
|
||||
|
BIN
amdguid/assets/icons/ports2.jpg
Normal file
BIN
amdguid/assets/icons/ports2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
@ -1,11 +1,12 @@
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::sync::Arc;
|
||||
|
||||
use amdgpu::pidfile::ports::Output;
|
||||
use amdgpu::pidfile::ports::{Output, OutputType};
|
||||
use amdgpu::pidfile::Pid;
|
||||
use egui::Ui;
|
||||
use epaint::ColorImage;
|
||||
use epi::Frame;
|
||||
use image::{ImageBuffer, ImageFormat, RgbaImage};
|
||||
use image::{GenericImageView, ImageBuffer, ImageFormat};
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use crate::widgets::outputs_settings::OutputsSettings;
|
||||
@ -83,113 +84,55 @@ static RELOAD_PID_LIST_DELAY: u8 = 18;
|
||||
#[cfg(debug_assertions)]
|
||||
static RELOAD_PID_LIST_DELAY: u8 = 80;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub enum ImageType {
|
||||
Vga,
|
||||
MiniDvi,
|
||||
Hdmi,
|
||||
Audio,
|
||||
OptimalAudio,
|
||||
Dvi,
|
||||
Thunderbolt,
|
||||
DisplayPort,
|
||||
MiniDisplayPort,
|
||||
FireWire400,
|
||||
Ps2,
|
||||
Sata,
|
||||
ESata,
|
||||
Ethernet,
|
||||
FireWire800,
|
||||
UsbTypeA,
|
||||
UsbTypeB,
|
||||
UsbTypeC,
|
||||
MicroUsb,
|
||||
MimiUsb,
|
||||
}
|
||||
|
||||
impl ImageType {
|
||||
pub fn to_coords(&self) -> (u32, u32) {
|
||||
match self {
|
||||
ImageType::Vga => (0, 0),
|
||||
ImageType::MiniDvi => (160, 0),
|
||||
ImageType::Hdmi => (320, 0),
|
||||
ImageType::Audio => (480, 0),
|
||||
ImageType::OptimalAudio => (640, 0),
|
||||
//
|
||||
ImageType::Dvi => (0, 160),
|
||||
ImageType::Thunderbolt => (160, 160),
|
||||
ImageType::DisplayPort => (320, 160),
|
||||
ImageType::MiniDisplayPort => (480, 160),
|
||||
ImageType::FireWire400 => (640, 160),
|
||||
//
|
||||
ImageType::Ps2 => (0, 320),
|
||||
ImageType::Sata => (160, 320),
|
||||
ImageType::ESata => (320, 320),
|
||||
ImageType::Ethernet => (480, 320),
|
||||
ImageType::FireWire800 => (640, 320),
|
||||
//
|
||||
ImageType::UsbTypeA => (0, 480),
|
||||
ImageType::UsbTypeB => (160, 480),
|
||||
ImageType::UsbTypeC => (320, 480),
|
||||
ImageType::MicroUsb => (480, 480),
|
||||
ImageType::MimiUsb => (640, 480),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StatefulConfig {
|
||||
pub config: FanConfig,
|
||||
pub state: ChangeState,
|
||||
pub images: HashMap<ImageType, RgbaImage>,
|
||||
pub textures: HashMap<OutputType, epaint::TextureHandle>,
|
||||
}
|
||||
|
||||
impl StatefulConfig {
|
||||
pub fn new(config: FanConfig) -> Self {
|
||||
let compact = image::load_from_memory_with_format(
|
||||
include_bytes!("../assets/icons/ports.jpg"),
|
||||
ImageFormat::Jpeg,
|
||||
)
|
||||
.unwrap()
|
||||
.into_rgba8();
|
||||
let images = [
|
||||
ImageType::Vga,
|
||||
ImageType::MiniDvi,
|
||||
ImageType::Hdmi,
|
||||
ImageType::Audio,
|
||||
ImageType::OptimalAudio,
|
||||
ImageType::Dvi,
|
||||
ImageType::Thunderbolt,
|
||||
ImageType::DisplayPort,
|
||||
ImageType::MiniDisplayPort,
|
||||
ImageType::FireWire400,
|
||||
ImageType::Ps2,
|
||||
ImageType::Sata,
|
||||
ImageType::ESata,
|
||||
ImageType::Ethernet,
|
||||
ImageType::FireWire800,
|
||||
ImageType::UsbTypeA,
|
||||
ImageType::UsbTypeB,
|
||||
ImageType::UsbTypeC,
|
||||
ImageType::MicroUsb,
|
||||
ImageType::MimiUsb,
|
||||
]
|
||||
.iter()
|
||||
.fold(HashMap::with_capacity(20), |mut memo, ty| {
|
||||
let (offset_x, offset_y) = ty.to_coords();
|
||||
let mut part = ImageBuffer::new(160, 160);
|
||||
for x in 0..160 {
|
||||
for y in 0..160 {
|
||||
part.put_pixel(x, y, compact.get_pixel(x + offset_x, y + offset_y).clone());
|
||||
}
|
||||
}
|
||||
memo.insert(*ty, part);
|
||||
memo
|
||||
});
|
||||
let textures = HashMap::with_capacity(40);
|
||||
|
||||
Self {
|
||||
config,
|
||||
state: ChangeState::New,
|
||||
images,
|
||||
textures,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_textures(&mut self, ui: &mut Ui) {
|
||||
if !self.textures.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 80x80
|
||||
let image = {
|
||||
let bytes = include_bytes!("../assets/icons/ports2.jpg");
|
||||
image::load_from_memory_with_format(bytes, ImageFormat::Jpeg).unwrap()
|
||||
};
|
||||
|
||||
let ctx = ui.ctx();
|
||||
|
||||
for ty in OutputType::all() {
|
||||
let (offset_x, offset_y) = ty.to_coords();
|
||||
let mut img = ImageBuffer::new(80, 80);
|
||||
for x in 0..80 {
|
||||
for y in 0..80 {
|
||||
img.put_pixel(x, y, image.get_pixel(x + offset_x, y + offset_y));
|
||||
}
|
||||
}
|
||||
|
||||
let size = [img.width() as _, img.height() as _];
|
||||
let pixels = img.as_flat_samples();
|
||||
let id = ctx.load_texture(
|
||||
String::from(ty.name()),
|
||||
epaint::ImageData::Color(ColorImage::from_rgba_unmultiplied(
|
||||
size,
|
||||
pixels.as_slice(),
|
||||
)),
|
||||
);
|
||||
self.textures.insert(ty, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -228,6 +171,8 @@ impl AmdGui {
|
||||
}
|
||||
|
||||
pub fn ui(&mut self, ui: &mut Ui) {
|
||||
self.config.load_textures(ui);
|
||||
|
||||
match self.page {
|
||||
Page::Config => {
|
||||
self.change_fan_settings
|
||||
@ -277,7 +222,7 @@ impl AmdGui {
|
||||
let mut names = outputs.iter().fold(
|
||||
Vec::with_capacity(outputs.len()),
|
||||
|mut set, output| {
|
||||
set.push(format!("{}", output.card));
|
||||
set.push(output.card.clone());
|
||||
set
|
||||
},
|
||||
);
|
||||
|
@ -1,10 +1,13 @@
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use glium::glutin;
|
||||
use image::RgbaImage;
|
||||
use parking_lot::Mutex;
|
||||
use tokio::sync::mpsc::UnboundedReceiver;
|
||||
|
||||
use crate::app::AmdGui;
|
||||
use crate::app::{AmdGui, ImageStorage, ImageType};
|
||||
use crate::backend::create_ui;
|
||||
|
||||
fn create_display(event_loop: &glutin::event_loop::EventLoop<()>) -> glium::Display {
|
||||
|
@ -10,12 +10,12 @@ use std::sync::Arc;
|
||||
use egui::panel::TopBottomSide;
|
||||
use egui::{Layout, PointerButton};
|
||||
#[cfg(feature = "xorg-glium")]
|
||||
pub use glium_backend::run_app;
|
||||
pub use glium_backend::*;
|
||||
#[cfg(feature = "xorg-glow")]
|
||||
pub use glow_backend::run_app;
|
||||
pub use glow_backend::*;
|
||||
use parking_lot::Mutex;
|
||||
#[cfg(feature = "wayland")]
|
||||
pub use wayland_backend::run_app;
|
||||
pub use wayland_backend::*;
|
||||
|
||||
use crate::app::Page;
|
||||
use crate::AmdGui;
|
||||
|
@ -81,7 +81,7 @@ pub fn run_app(amd_gui: Arc<Mutex<AmdGui>>, _receiver: UnboundedReceiver<bool>)
|
||||
|
||||
let event_loop = EventLoop::new();
|
||||
let surface = WindowBuilder::new()
|
||||
.with_title("egui_vulkano demo")
|
||||
.with_title("AMD GUID")
|
||||
.with_fullscreen(Some(Fullscreen::Borderless(None)))
|
||||
.build_vk_surface(&event_loop, instance.clone())
|
||||
.unwrap();
|
||||
@ -176,32 +176,34 @@ pub fn run_app(amd_gui: Arc<Mutex<AmdGui>>, _receiver: UnboundedReceiver<bool>)
|
||||
};
|
||||
|
||||
mod vs {
|
||||
#![allow(clippy::needless_question_mark)]
|
||||
vulkano_shaders::shader! {
|
||||
ty: "vertex",
|
||||
src: "
|
||||
#version 450
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 position;
|
||||
layout(location = 0) in vec2 position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
}
|
||||
"
|
||||
void main() {
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
}
|
||||
"
|
||||
}
|
||||
}
|
||||
|
||||
mod fs {
|
||||
#![allow(clippy::needless_question_mark)]
|
||||
vulkano_shaders::shader! {
|
||||
ty: "fragment",
|
||||
src: "
|
||||
#version 450
|
||||
#version 450
|
||||
|
||||
layout(location = 0) out vec4 f_color;
|
||||
layout(location = 0) out vec4 f_color;
|
||||
|
||||
void main() {
|
||||
f_color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
"
|
||||
void main() {
|
||||
f_color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
"
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,7 +222,7 @@ pub fn run_app(amd_gui: Arc<Mutex<AmdGui>>, _receiver: UnboundedReceiver<bool>)
|
||||
},
|
||||
passes: [
|
||||
{ color: [color], depth_stencil: {}, input: [] },
|
||||
{ color: [color], depth_stencil: {}, input: [] } // Create a second renderpass to draw egui
|
||||
{ color: [color], depth_stencil: {}, input: [] } // Create a second render-pass to draw egui
|
||||
]
|
||||
)
|
||||
.unwrap();
|
||||
@ -231,7 +233,7 @@ pub fn run_app(amd_gui: Arc<Mutex<AmdGui>>, _receiver: UnboundedReceiver<bool>)
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
.fragment_shader(fs.entry_point("main").unwrap(), ())
|
||||
.render_pass(Subpass::from(render_pass.clone().into(), 0).unwrap())
|
||||
.render_pass(Subpass::from(render_pass.clone(), 0).unwrap())
|
||||
.build(device.clone())
|
||||
.unwrap();
|
||||
|
||||
@ -241,7 +243,8 @@ pub fn run_app(amd_gui: Arc<Mutex<AmdGui>>, _receiver: UnboundedReceiver<bool>)
|
||||
depth_range: 0.0..1.0,
|
||||
};
|
||||
|
||||
let mut framebuffers = window_size_dependent_setup(&images, render_pass.clone(), &mut viewport);
|
||||
let mut frame_buffers =
|
||||
window_size_dependent_setup(&images, render_pass.clone(), &mut viewport);
|
||||
|
||||
let mut recreate_swapchain = false;
|
||||
|
||||
@ -261,9 +264,6 @@ pub fn run_app(amd_gui: Arc<Mutex<AmdGui>>, _receiver: UnboundedReceiver<bool>)
|
||||
|
||||
//Set up some window to look at for the test
|
||||
|
||||
// let mut my_texture = egui_ctx.load_texture("my_texture",
|
||||
// ColorImage::example());
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
match event {
|
||||
Event::WindowEvent {
|
||||
@ -304,7 +304,7 @@ pub fn run_app(amd_gui: Arc<Mutex<AmdGui>>, _receiver: UnboundedReceiver<bool>)
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
framebuffers = window_size_dependent_setup(
|
||||
frame_buffers = window_size_dependent_setup(
|
||||
&new_images,
|
||||
render_pass.clone(),
|
||||
&mut viewport,
|
||||
@ -352,7 +352,7 @@ pub fn run_app(amd_gui: Arc<Mutex<AmdGui>>, _receiver: UnboundedReceiver<bool>)
|
||||
// Do your usual rendering
|
||||
builder
|
||||
.begin_render_pass(
|
||||
framebuffers[image_num].clone(),
|
||||
frame_buffers[image_num].clone(),
|
||||
SubpassContents::Inline,
|
||||
clear_values,
|
||||
)
|
||||
|
@ -143,5 +143,5 @@ pub struct ExplicitGenerator {
|
||||
#[inline(always)]
|
||||
pub fn y_intersection(p1: &Pos2, p2: &Pos2, y: f32) -> Option<f32> {
|
||||
((p1.y > y && p2.y < y) || (p1.y < y && p2.y > y))
|
||||
.then(|| ((y * (p1.x - p2.x)) - (p1.x * p2.y - p1.y * p2.x)) / (p1.y - p2.y))
|
||||
.then_some(((y * (p1.x - p2.x)) - (p1.x * p2.y - p1.y * p2.x)) / (p1.y - p2.y))
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ impl PlotItem for Points {
|
||||
let default_stroke = Stroke::new(stroke_size, *color);
|
||||
let mut stem_stroke = default_stroke;
|
||||
let stroke = (!filled)
|
||||
.then(|| default_stroke)
|
||||
.then_some(default_stroke)
|
||||
.unwrap_or_else(Stroke::none);
|
||||
let fill = filled.then(|| *color).unwrap_or_default();
|
||||
|
||||
|
@ -126,7 +126,7 @@ impl Values {
|
||||
) -> Option<RangeInclusive<f64>> {
|
||||
let start = range1.start().max(*range2.start());
|
||||
let end = range1.end().min(*range2.end());
|
||||
(start < end).then(|| start..=end)
|
||||
(start < end).then_some(start..=end)
|
||||
}
|
||||
|
||||
pub(crate) fn get_bounds(&self) -> Bounds {
|
||||
|
@ -149,10 +149,12 @@ impl ChangeFanSettings {
|
||||
});
|
||||
}
|
||||
|
||||
#[allow(clippy::explicit_auto_deref)]
|
||||
fn save_config(config: FanConfig, state: &mut StatefulConfig) {
|
||||
state.state = ChangeState::Reloading;
|
||||
|
||||
let config = config.lock();
|
||||
|
||||
let c: &amdgpu_config::fan::Config = &*config;
|
||||
let content = match toml::to_string(c) {
|
||||
Err(e) => {
|
||||
|
@ -15,6 +15,7 @@ pub struct CoolingPerformance {
|
||||
}
|
||||
|
||||
impl CoolingPerformance {
|
||||
#[allow(clippy::explicit_auto_deref)]
|
||||
pub fn new(capacity: usize, fan_config: FanConfig) -> Self {
|
||||
let amd_mon = amdgpu::hw_mon::open_hw_mon(Card(0))
|
||||
.map(|hw| amdmond_lib::AmdMon::wrap(hw, &*fan_config.lock()))
|
||||
|
@ -260,6 +260,7 @@ impl DragPlotPrepared {
|
||||
}
|
||||
};
|
||||
|
||||
#[allow(clippy::explicit_auto_deref)]
|
||||
shapes.push(Shape::text(
|
||||
&*ui.fonts(),
|
||||
pointer + vec2(3.0, -2.0),
|
||||
|
@ -43,7 +43,7 @@ impl LegendWidget {
|
||||
LegendEntry::new(color, checked)
|
||||
});
|
||||
});
|
||||
(!entries.is_empty()).then(|| Self {
|
||||
(!entries.is_empty()).then_some(Self {
|
||||
rect,
|
||||
entries,
|
||||
config,
|
||||
|
@ -1,69 +1,58 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use amdgpu::pidfile::ports::Output;
|
||||
use egui::{Response, Sense, Ui, Vec2};
|
||||
use epaint::Stroke;
|
||||
|
||||
pub struct OutputWidget<'output, 'textures> {
|
||||
use crate::app::StatefulConfig;
|
||||
|
||||
pub struct OutputWidget<'output, 'stateful> {
|
||||
output: &'output Output,
|
||||
textures: &'textures HashMap<String, egui::TextureHandle>,
|
||||
state: &'stateful mut StatefulConfig,
|
||||
}
|
||||
|
||||
impl<'output, 'textures> OutputWidget<'output, 'textures> {
|
||||
pub fn new(
|
||||
output: &'output Output,
|
||||
textures: &'textures HashMap<String, egui::TextureHandle>,
|
||||
) -> Self {
|
||||
Self { output, textures }
|
||||
impl<'output, 'stateful> OutputWidget<'output, 'stateful> {
|
||||
pub fn new(output: &'output Output, state: &'stateful mut StatefulConfig) -> Self {
|
||||
Self { output, state }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'output, 'textures> egui::Widget for OutputWidget<'output, 'textures> {
|
||||
impl<'output, 'stateful> egui::Widget for OutputWidget<'output, 'stateful> {
|
||||
fn ui(self, ui: &mut Ui) -> Response {
|
||||
let (rect, res) = ui.allocate_exact_size(Vec2::new(80.0, 70.0), Sense::click());
|
||||
// let _transform = ScreenTransform::new(rect, Bounds::new_symmetrical(1.0),
|
||||
// false, false); let _frame = *transform.frame();
|
||||
// eprintln!("min {:?} max {:?}", frame.min, frame.max);
|
||||
let painter = ui.painter(); //.sub_region(*transform.frame());
|
||||
let (rect, res) = ui.allocate_exact_size(Vec2::new(80.0, 80.0), Sense::click());
|
||||
if let Some(handle) = self.output.ty.and_then(|ty| self.state.textures.get(&ty)) {
|
||||
ui.image(handle.id(), handle.size_vec2());
|
||||
} else {
|
||||
let painter = ui.painter();
|
||||
painter.rect_filled(rect, 0.0, epaint::color::Color32::DARK_RED);
|
||||
painter.rect(rect, 2.0, epaint::color::Color32::DARK_RED, {
|
||||
Stroke {
|
||||
width: 1.0,
|
||||
color: epaint::color::Color32::GREEN,
|
||||
}
|
||||
});
|
||||
|
||||
painter.rect_filled(rect, 0.0, epaint::color::Color32::DARK_RED);
|
||||
painter.rect(rect, 2.0, epaint::color::Color32::DARK_RED, {
|
||||
let mut s = Stroke::default();
|
||||
s.color = epaint::color::Color32::GREEN;
|
||||
s.width = 1.0;
|
||||
s
|
||||
});
|
||||
let rect_middle_point = (rect.max - rect.min) / 2.0;
|
||||
|
||||
let rect_middle_point = (rect.max - rect.min) / 2.0;
|
||||
painter.circle_filled(
|
||||
rect.min + Vec2::new(rect_middle_point.x / 2.0, rect_middle_point.y),
|
||||
3.0,
|
||||
epaint::color::Color32::GREEN,
|
||||
);
|
||||
painter.circle_filled(
|
||||
rect.min + rect_middle_point,
|
||||
3.0,
|
||||
epaint::color::Color32::GREEN,
|
||||
);
|
||||
|
||||
painter.circle_filled(
|
||||
rect.min + Vec2::new(rect_middle_point.x / 2.0, rect_middle_point.y),
|
||||
3.0,
|
||||
epaint::color::Color32::GREEN,
|
||||
);
|
||||
painter.circle_filled(
|
||||
rect.min + rect_middle_point,
|
||||
3.0,
|
||||
epaint::color::Color32::GREEN,
|
||||
);
|
||||
|
||||
painter.circle_filled(
|
||||
rect.min
|
||||
+ Vec2::new(
|
||||
rect_middle_point.x + (rect_middle_point.x / 2.0),
|
||||
rect_middle_point.y,
|
||||
),
|
||||
3.0,
|
||||
epaint::color::Color32::GREEN,
|
||||
);
|
||||
painter.circle_filled(
|
||||
rect.min
|
||||
+ Vec2::new(
|
||||
rect_middle_point.x + (rect_middle_point.x / 2.0),
|
||||
rect_middle_point.y,
|
||||
),
|
||||
3.0,
|
||||
epaint::color::Color32::GREEN,
|
||||
);
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
fn icon(name: &str, textures: &HashMap<String, egui::TextureHandle>) {
|
||||
if let Some(_texture) = textures.get(name) {
|
||||
//
|
||||
} else {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
@ -1,52 +1,22 @@
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use amdgpu::pidfile::ports::{Output, Status};
|
||||
use egui::Ui;
|
||||
use epaint::ColorImage;
|
||||
use image::ImageFormat;
|
||||
use egui::{RichText, Ui, WidgetText};
|
||||
use epaint::Color32;
|
||||
|
||||
use crate::app::StatefulConfig;
|
||||
use crate::widgets::output_widget::OutputWidget;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OutputsSettings {
|
||||
textures: HashMap<String, egui::TextureHandle>,
|
||||
}
|
||||
pub struct OutputsSettings {}
|
||||
|
||||
impl OutputsSettings {
|
||||
pub fn draw(
|
||||
&mut self,
|
||||
ui: &mut Ui,
|
||||
_state: &mut StatefulConfig,
|
||||
state: &mut StatefulConfig,
|
||||
outputs: &BTreeMap<String, Vec<Output>>,
|
||||
) {
|
||||
outputs.values().flatten().for_each(|output| {
|
||||
// 160x160
|
||||
let image = {
|
||||
let bytes = include_bytes!("../../assets/icons/ports.jpg");
|
||||
image::load_from_memory(bytes).unwrap()
|
||||
};
|
||||
|
||||
for (_idx, _pixel, _p) in image.to_rgba8().enumerate_pixels() {
|
||||
// let bytes = pixel.;
|
||||
// eprintln!("{:?}", bytes);
|
||||
}
|
||||
|
||||
if !self.textures.contains_key(&output.port_type) {
|
||||
let img = image::load_from_memory_with_format(
|
||||
include_bytes!("../../assets/icons/ports.jpg"),
|
||||
ImageFormat::Jpeg,
|
||||
)
|
||||
.unwrap();
|
||||
let image_buffer = img.to_rgba8();
|
||||
let size = [image.width() as _, image.height() as _];
|
||||
let pixels = image_buffer.as_flat_samples();
|
||||
let _ = ui.ctx().load_texture(
|
||||
output.port_type.clone(),
|
||||
ColorImage::from_rgba_unmultiplied(size, pixels.as_slice()),
|
||||
);
|
||||
}
|
||||
});
|
||||
let _available = ui.available_rect_before_wrap();
|
||||
|
||||
ui.vertical(|ui| {
|
||||
@ -57,7 +27,7 @@ impl OutputsSettings {
|
||||
ui.horizontal_top(|ui| {
|
||||
outputs.iter().for_each(|output| {
|
||||
ui.vertical(|ui| {
|
||||
ui.add(OutputWidget::new(output, &self.textures));
|
||||
ui.add(OutputWidget::new(output, state));
|
||||
|
||||
ui.label(format!("port_number {}", output.port_number));
|
||||
ui.label(format!("port_type {:?}", output.port_type));
|
||||
@ -66,17 +36,27 @@ impl OutputsSettings {
|
||||
"port_name {}",
|
||||
output.port_name.as_deref().unwrap_or_default()
|
||||
));
|
||||
ui.label(match output.status {
|
||||
Status::Connected => "Connected",
|
||||
Status::Disconnected => "Disconnected",
|
||||
});
|
||||
|
||||
let state = WidgetText::RichText(
|
||||
RichText::new(match output.status {
|
||||
Status::Connected => "Connected",
|
||||
Status::Disconnected => "Disconnected",
|
||||
})
|
||||
.color(
|
||||
match output.status {
|
||||
Status::Connected => Color32::DARK_GREEN,
|
||||
Status::Disconnected => Color32::GRAY,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
ui.label(state);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
// eprintln!("==============================================================");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,25 @@ fn parse_output(entry: DirEntry) -> Option<Output> {
|
||||
.map(String::from)
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter();
|
||||
|
||||
let modes = std::fs::read_to_string(entry.path().join("modes"))
|
||||
.unwrap_or_default()
|
||||
.lines()
|
||||
.filter_map(|s| {
|
||||
let mut it = s.split('x');
|
||||
let width = it.next().and_then(|s| s.parse::<u16>().ok())?;
|
||||
let height = it.next().and_then(|s| s.parse::<u16>().ok())?;
|
||||
Some(OutputMode { width, height })
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let card = it.next()?.strip_prefix("card")?.to_string();
|
||||
let port_type = it.next()?;
|
||||
let mut output = Output {
|
||||
card: it.next()?.strip_prefix("card")?.to_string(),
|
||||
port_type: it.next()?,
|
||||
card,
|
||||
ty: OutputType::parse_str(&port_type),
|
||||
port_type,
|
||||
modes,
|
||||
..Default::default()
|
||||
};
|
||||
let mut it = it.rev();
|
||||
|
Loading…
Reference in New Issue
Block a user