This commit is contained in:
2Shirt 2025-01-15 19:17:05 -08:00
parent 9d6fa954b2
commit 353f2d5570
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
5 changed files with 152 additions and 21 deletions

View file

@ -18,6 +18,7 @@ use strum::Display;
use crate::{ use crate::{
components::popup::Type, components::popup::Type,
line::DVLine,
state::Mode, state::Mode,
system::{ system::{
disk::{Disk, PartitionTableType}, disk::{Disk, PartitionTableType},
@ -35,6 +36,8 @@ pub enum Action {
SelectDriver(Driver), SelectDriver(Driver),
SelectTableType(PartitionTableType), SelectTableType(PartitionTableType),
UpdateDiskList(Vec<Disk>), UpdateDiskList(Vec<Disk>),
UpdateLeft(Vec<DVLine>, Vec<String>),
UpdateRight(Vec<DVLine>, Vec<String>),
// Screens // Screens
DismissPopup, DismissPopup,
DisplayPopup(Type, String), DisplayPopup(Type, String),

View file

@ -25,6 +25,7 @@ use crossterm::event::KeyEvent;
use ratatui::{ use ratatui::{
layout::{Constraint, Direction, Layout}, layout::{Constraint, Direction, Layout},
prelude::Rect, prelude::Rect,
style::Color,
}; };
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tracing::{debug, info}; use tracing::{debug, info};
@ -35,9 +36,11 @@ use crate::{
footer::Footer, fps::FpsCounter, left::Left, popup, right::Right, title::Title, Component, footer::Footer, fps::FpsCounter, left::Left, popup, right::Right, title::Title, Component,
}, },
config::Config, config::Config,
line::DVLine,
state::{CloneSettings, Mode}, state::{CloneSettings, Mode},
system::{ system::{
boot, boot,
cpu::get_cpu_name,
diskpart::build_dest_format_script, diskpart::build_dest_format_script,
drivers::{self}, drivers::{self},
}, },
@ -240,7 +243,6 @@ impl App {
String::from("COMPLETE\n\n\nThank you for using this tool!"), String::from("COMPLETE\n\n\nThank you for using this tool!"),
))?; ))?;
} }
_ => {}
} }
Ok(()) Ok(())
} }
@ -488,3 +490,68 @@ fn get_chunks(r: Rect) -> Vec<Rect> {
// Done // Done
chunks chunks
} }
fn get_right_headers(prev_mode: Mode, cur_mode: Mode) -> Vec<DVLine> {
let mut headers = Vec::new();
// Main header
match (prev_mode, cur_mode) {
(_, Mode::InstallDrivers) => headers.push(DVLine {
line_parts: vec![String::from("CPU"), get_cpu_name()],
line_colors: vec![Color::Cyan, Color::Reset],
}),
(_, Mode::SelectDisks | Mode::SelectTableType)
| (Mode::SelectDisks | Mode::SelectTableType, Mode::Confirm) => {
// Source Disk Details
headers.push(DVLine {
line_parts: vec![String::from("Source")],
line_colors: vec![Color::Cyan],
});
headers.push(DVLine {
line_parts: vec![String::new()],
line_colors: vec![Color::Reset],
});
headers.push(DVLine {
line_parts: vec![String::new()],
line_colors: vec![Color::Reset],
});
headers.push(DVLine {
line_parts: vec![format!(
"{:<8} {:>11} {:<4} {:<4} {}",
"Disk ID", "Size", "Conn", "Type", "Model (Serial)"
)],
line_colors: vec![Color::Green],
});
}
_ => {}
}
// First selection
match (prev_mode, cur_mode) {
(_, Mode::SelectDisks | Mode::SelectTableType)
| (Mode::SelectDisks | Mode::SelectTableType, Mode::Confirm) => headers.push(DVLine {
line_parts: vec![String::from("Source"), get_cpu_name()],
line_colors: vec![Color::Cyan, Color::Reset],
}),
(Mode::SelectParts, Mode::Confirm) => {
headers.push(DVLine {
line_parts: vec![String::from("Dest")],
line_colors: vec![Color::Cyan],
});
// Disk details
// Part details
}
_ => {}
};
// Source
// SelectDisks
// SelectTableType
// Confirm (for above ^)
// Dest
// SelectParts
// (SelectParts, Confirm)
// Second selection
headers
}

View file

@ -23,40 +23,35 @@ use tokio::sync::mpsc::UnboundedSender;
use tracing::info; use tracing::info;
use super::{state::StatefulList, Component}; use super::{state::StatefulList, Component};
use crate::{ use crate::{action::Action, config::Config, state::Mode};
action::Action,
config::Config,
state::Mode,
system::{
cpu::get_cpu_name,
disk::{Disk, Partition, PartitionTableType},
},
};
#[derive(Default)] #[derive(Default)]
pub struct Right { pub struct Right<'a> {
command_tx: Option<UnboundedSender<Action>>, command_tx: Option<UnboundedSender<Action>>,
config: Config, config: Config,
cur_mode: Mode, cur_mode: Mode,
list_disks: StatefulList<Disk>, list_desc: StatefulList<Vec<text::Line<'a>>>,
list_parts: StatefulList<Partition>, list_item: StatefulList<Vec<text::Line<'a>>>,
prev_mode: Mode, prev_mode: Mode,
selected_disks: Vec<Option<usize>>,
selections: Vec<Option<usize>>, selections: Vec<Option<usize>>,
table_type: Option<PartitionTableType>, title: String,
} }
impl Right { impl Right<'_> {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
selected_disks: vec![None, None],
selections: vec![None, None], selections: vec![None, None],
title: String::from("Info"),
..Default::default() ..Default::default()
} }
} }
pub fn set_title(&mut self, new_title: &str) {
self.title = String::from(new_title);
}
} }
impl Component for Right { impl Component for Right<'_> {
fn handle_key_event(&mut self, key: KeyEvent) -> Result<Option<Action>> { fn handle_key_event(&mut self, key: KeyEvent) -> Result<Option<Action>> {
let _ = key; // to appease clippy let _ = key; // to appease clippy
Ok(None) Ok(None)
@ -149,9 +144,16 @@ impl Component for Right {
} }
} }
} }
Action::UpdateRight(new_descs, new_items) => {
let lines: Vec<text::Line> = new_descs.iter().map(|d| d.as_line()).collect();
let items: Vec<text::Line> = new_items.iter().map(|p| text::Line::from(p.as_str())).collect();
self.list_desc.set_items(lines);
// TODO / FIXME
}
_ => {} _ => {}
} }
Ok(None) Ok(None)E0277
body_text.push(Line::from(Span::raw(format!("CPU: {}", get_cpu_name()))));
} }
fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> { fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> {
@ -161,13 +163,34 @@ impl Component for Right {
.areas(area); .areas(area);
// Title // Title
let title_text = String::from("Info"); let title = Paragraph::new(Line::from(self.title).centered())
let title = Paragraph::new(Line::from(title_text).centered())
.block(Block::default().borders(Borders::NONE)); .block(Block::default().borders(Borders::NONE));
frame.render_widget(title, title_area); frame.render_widget(title, title_area);
// Body // Body
let mut body_text = Vec::new(); let mut body_text = Vec::new();
if let Some(header) = self.list_desc.get(0) {
header.iter().map(|line| body_text.push(line));
}
if let Some(first_index) = self.selections[0] {
if let Some(first_desc) = self.list_desc.get(first_index + 1) {
first_desc.iter().map(|line| body_text.push(line));
}
if let Some(first_item) = self.list_item.get(first_index) {
first_item.iter().map(|line| body_text.push(line));
}
}
if let Some(second_index) = self.selections[1] {
if let Some(second_desc) = self.list_desc.get(second_index + 1) {
second_desc.iter().map(|line| body_text.push(line));
}
if let Some(second_item) = self.list_item.get(second_index) {
second_item.iter().map(|line| body_text.push(line));
}
}
// Body (Old)
let mut body_text = Vec::new();
match (self.prev_mode, self.cur_mode) { match (self.prev_mode, self.cur_mode) {
(_, Mode::InstallDrivers) => { (_, Mode::InstallDrivers) => {
body_text.push(Line::from(Span::raw(format!("CPU: {}", get_cpu_name())))); body_text.push(Line::from(Span::raw(format!("CPU: {}", get_cpu_name()))));

37
deja_vu/src/line.rs Normal file
View file

@ -0,0 +1,37 @@
// This file is part of Deja-vu.
//
// Deja-vu is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Deja-vu is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
//
use ratatui::{
style::{Color, Style},
text::{Line, Span},
};
use serde::{Deserialize, Serialize};
use std::iter::zip;
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DVLine {
pub line_parts: Vec<String>,
pub line_colors: Vec<Color>,
}
impl DVLine {
/// Convert to Line with colored span(s)
pub fn as_line(&self) -> Line {
let mut spans = Vec::new();
zip(self.line_parts.clone(), self.line_colors.clone())
.map(|(part, color)| spans.push(Span::styled(part, Style::default().fg(color))));
Line::from(spans)
}
}

View file

@ -25,6 +25,7 @@ mod cli;
mod components; mod components;
mod config; mod config;
mod errors; mod errors;
mod line;
mod logging; mod logging;
mod state; mod state;
mod system; mod system;