diff --git a/src/builders/build_basalt.rs b/src/builders/build_basalt.rs index 94f7b1c..e053fea 100644 --- a/src/builders/build_basalt.rs +++ b/src/builders/build_basalt.rs @@ -2,12 +2,17 @@ use crate::{ build_tools::{cmake::Cmake, git::Git}, file_utils::rm_rf, profile::Profile, + termcolor::TermColor, ui::job_worker::job::WorkerJob, }; use std::collections::{HashMap, VecDeque}; pub fn get_build_basalt_jobs(profile: &Profile, clean_build: bool) -> VecDeque { let mut jobs = VecDeque::::new(); + jobs.push_back(WorkerJob::new_printer( + "Building Basalt...", + Some(TermColor::Blue), + )); let git = Git { repo: profile diff --git a/src/builders/build_libsurvive.rs b/src/builders/build_libsurvive.rs index 3cf5837..1373828 100644 --- a/src/builders/build_libsurvive.rs +++ b/src/builders/build_libsurvive.rs @@ -2,6 +2,7 @@ use crate::{ build_tools::{cmake::Cmake, git::Git}, file_utils::rm_rf, profile::Profile, + termcolor::TermColor, ui::job_worker::job::WorkerJob, }; use std::{ @@ -11,6 +12,10 @@ use std::{ pub fn get_build_libsurvive_jobs(profile: &Profile, clean_build: bool) -> VecDeque { let mut jobs = VecDeque::::new(); + jobs.push_back(WorkerJob::new_printer( + "Building Libsurvive...", + Some(TermColor::Blue), + )); let git = Git { repo: profile diff --git a/src/builders/build_mercury.rs b/src/builders/build_mercury.rs index dd501b9..36b5c23 100644 --- a/src/builders/build_mercury.rs +++ b/src/builders/build_mercury.rs @@ -1,9 +1,17 @@ +use std::collections::VecDeque; + use crate::{ - constants::pkg_data_dir, paths::get_cache_dir, profile::Profile, ui::job_worker::job::WorkerJob, + constants::pkg_data_dir, paths::get_cache_dir, profile::Profile, termcolor::TermColor, + ui::job_worker::job::WorkerJob, }; -pub fn get_build_mercury_job(profile: &Profile) -> WorkerJob { - WorkerJob::new_cmd( +pub fn get_build_mercury_jobs(profile: &Profile) -> VecDeque { + let mut jobs = VecDeque::new(); + jobs.push_back(WorkerJob::new_printer( + "Building Mercury...", + Some(TermColor::Blue), + )); + jobs.push_back(WorkerJob::new_cmd( None, pkg_data_dir() .join("scripts/build_mercury.sh") @@ -13,5 +21,7 @@ pub fn get_build_mercury_job(profile: &Profile) -> WorkerJob { profile.prefix.to_string_lossy().to_string(), get_cache_dir().to_string_lossy().to_string(), ]), - ) + )); + + jobs } diff --git a/src/builders/build_monado.rs b/src/builders/build_monado.rs index 89490db..19fa3ba 100644 --- a/src/builders/build_monado.rs +++ b/src/builders/build_monado.rs @@ -2,6 +2,7 @@ use crate::{ build_tools::{cmake::Cmake, git::Git}, file_utils::rm_rf, profile::Profile, + termcolor::TermColor, ui::job_worker::job::WorkerJob, }; use std::{ @@ -11,6 +12,10 @@ use std::{ pub fn get_build_monado_jobs(profile: &Profile, clean_build: bool) -> VecDeque { let mut jobs = VecDeque::::new(); + jobs.push_back(WorkerJob::new_printer( + "Building Monado...", + Some(TermColor::Blue), + )); let git = Git { repo: profile diff --git a/src/builders/build_opencomposite.rs b/src/builders/build_opencomposite.rs index 84d8125..6e11175 100644 --- a/src/builders/build_opencomposite.rs +++ b/src/builders/build_opencomposite.rs @@ -2,6 +2,7 @@ use crate::{ build_tools::{cmake::Cmake, git::Git}, file_utils::rm_rf, profile::Profile, + termcolor::TermColor, ui::job_worker::job::WorkerJob, }; use std::{ @@ -11,6 +12,10 @@ use std::{ pub fn get_build_opencomposite_jobs(profile: &Profile, clean_build: bool) -> VecDeque { let mut jobs = VecDeque::::new(); + jobs.push_back(WorkerJob::new_printer( + "Building OpenComposite...", + Some(TermColor::Blue), + )); let git = Git { repo: profile diff --git a/src/builders/build_openhmd.rs b/src/builders/build_openhmd.rs index 1573816..5d272f3 100644 --- a/src/builders/build_openhmd.rs +++ b/src/builders/build_openhmd.rs @@ -2,6 +2,7 @@ use crate::{ build_tools::{cmake::Cmake, git::Git}, file_utils::rm_rf, profile::Profile, + termcolor::TermColor, ui::job_worker::job::WorkerJob, }; use std::{ @@ -11,6 +12,10 @@ use std::{ pub fn get_build_openhmd_jobs(profile: &Profile, clean_build: bool) -> VecDeque { let mut jobs = VecDeque::::new(); + jobs.push_back(WorkerJob::new_printer( + "Building OpenHMD...", + Some(TermColor::Blue), + )); let git = Git { repo: profile diff --git a/src/builders/build_wivrn.rs b/src/builders/build_wivrn.rs index 5859875..ad41824 100644 --- a/src/builders/build_wivrn.rs +++ b/src/builders/build_wivrn.rs @@ -2,6 +2,7 @@ use crate::{ build_tools::{cmake::Cmake, git::Git}, file_utils::rm_rf, profile::Profile, + termcolor::TermColor, ui::job_worker::job::WorkerJob, }; use std::{ @@ -11,6 +12,10 @@ use std::{ pub fn get_build_wivrn_jobs(profile: &Profile, clean_build: bool) -> VecDeque { let mut jobs = VecDeque::::new(); + jobs.push_back(WorkerJob::new_printer( + "Building WiVRn...", + Some(TermColor::Blue), + )); let git = Git { repo: profile diff --git a/src/log_level.rs b/src/log_level.rs index a6ea930..8d47161 100644 --- a/src/log_level.rs +++ b/src/log_level.rs @@ -1,6 +1,8 @@ use serde::{de::Visitor, Deserialize, Serialize}; use std::{fmt::Display, slice::Iter, str::FromStr}; +use crate::termcolor::TermColor; + #[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize)] pub enum LogLevel { Trace, @@ -89,6 +91,17 @@ impl LogLevel { Self::Error => 99, } } + + pub fn colored(&self) -> String { + match self { + Self::Trace => TermColor::Gray, + Self::Debug => TermColor::Gray, + Self::Info => TermColor::Blue, + Self::Warning => TermColor::Yellow, + Self::Error => TermColor::Red, + } + .colorize(&self.to_string()) + } } impl PartialOrd for LogLevel { diff --git a/src/main.rs b/src/main.rs index a36fdb8..9c488dd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,6 +42,7 @@ pub mod runner; pub mod runner_pipeline; pub mod steam_linux_runtime_injector; pub mod steamvr_utils; +pub mod termcolor; pub mod ui; pub mod xdg; pub mod xr_devices; diff --git a/src/termcolor.rs b/src/termcolor.rs new file mode 100644 index 0000000..c93a461 --- /dev/null +++ b/src/termcolor.rs @@ -0,0 +1,49 @@ +const ANSI_ESCAPE_BEGIN: &str = "\u{001B}["; +const ANSI_ESCAPE_END: &str = "m"; + +const ANSI_RESET: u8 = 0; + +const ANSI_BLACK: u8 = 30; +const ANSI_RED: u8 = 31; +const ANSI_GREEN: u8 = 32; +const ANSI_YELLOW: u8 = 33; +const ANSI_BLUE: u8 = 34; +const ANSI_PURPLE: u8 = 35; +const ANSI_CYAN: u8 = 36; +const ANSI_WHITE: u8 = 37; + +// const ANSI_BG_ADDENDUM: u8 = 10; +const ANSI_BRIGHT_ADDENDUM: u8 = 60; + +#[derive(Debug, Clone, Copy)] +pub enum TermColor { + Black, + Red, + Green, + Yellow, + Blue, + Purple, + Cyan, + White, + Gray, +} + +impl TermColor { + fn code(&self) -> u8 { + match self { + Self::Black => ANSI_BLACK, + Self::Red => ANSI_RED, + Self::Green => ANSI_GREEN, + Self::Yellow => ANSI_YELLOW, + Self::Blue => ANSI_BLUE, + Self::Purple => ANSI_PURPLE, + Self::Cyan => ANSI_CYAN, + Self::White => ANSI_WHITE, + Self::Gray => ANSI_BLACK + ANSI_BRIGHT_ADDENDUM, + } + } + + pub fn colorize(&self, s: &str) -> String { + format!("{ANSI_ESCAPE_BEGIN}{code}{ANSI_ESCAPE_END}{s}{ANSI_ESCAPE_BEGIN}{ANSI_RESET}{ANSI_ESCAPE_END}", code = self.code()) + } +} diff --git a/src/ui/app.rs b/src/ui/app.rs index 463368c..fecd98e 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -12,7 +12,7 @@ use super::util::{copy_text, open_with_default_handler}; use super::wivrn_conf_editor::{WivrnConfEditor, WivrnConfEditorInit, WivrnConfEditorMsg}; use crate::builders::build_basalt::get_build_basalt_jobs; use crate::builders::build_libsurvive::get_build_libsurvive_jobs; -use crate::builders::build_mercury::get_build_mercury_job; +use crate::builders::build_mercury::get_build_mercury_jobs; use crate::builders::build_monado::get_build_monado_jobs; use crate::builders::build_opencomposite::get_build_opencomposite_jobs; use crate::builders::build_openhmd::get_build_openhmd_jobs; @@ -460,7 +460,7 @@ impl SimpleComponent for App { } if profile.features.mercury_enabled { missing_deps.extend(get_missing_mercury_deps()); - jobs.push_back(get_build_mercury_job(&profile)); + jobs.extend(get_build_mercury_jobs(&profile)); } jobs.extend(match profile.xrservice_type { XRServiceType::Monado => get_build_monado_jobs(&profile, clean_build), diff --git a/src/ui/debug_view.rs b/src/ui/debug_view.rs index 5d49388..62a4885 100644 --- a/src/ui/debug_view.rs +++ b/src/ui/debug_view.rs @@ -172,7 +172,7 @@ impl SimpleComponent for DebugView { false => None, true => Some(format!( "{lvl}\t[{file}:{func}]\r\n\t{msg}\r\n", - lvl = o.level, + lvl = o.level.colored(), file = o.file, func = o.func, msg = o.message.replace('\n', "\r\n") diff --git a/src/ui/job_worker/job.rs b/src/ui/job_worker/job.rs index 5c5102e..69c8c1d 100644 --- a/src/ui/job_worker/job.rs +++ b/src/ui/job_worker/job.rs @@ -1,5 +1,7 @@ use std::collections::HashMap; +use crate::termcolor::TermColor; + #[derive(Debug, Clone)] pub struct CmdWorkerData { pub environment: HashMap, @@ -44,6 +46,21 @@ impl WorkerJob { }) } + pub fn new_printer(txt: &str, color: Option) -> Self { + let out = format!( + "{}\n", + if let Some(c) = color { + c.colorize(txt) + } else { + txt.to_string() + } + ); + Self::new_func(Box::new(move || FuncWorkerOut { + out: vec![out], + success: true, + })) + } + pub fn new_func(func: Box FuncWorkerOut + Send + Sync + 'static>) -> Self { Self::Func(FuncWorkerData { func }) } diff --git a/src/ui/term_widget.rs b/src/ui/term_widget.rs index 73bc1e9..b51b0c6 100644 --- a/src/ui/term_widget.rs +++ b/src/ui/term_widget.rs @@ -1,6 +1,6 @@ use gtk4::gdk; use relm4::adw; -use vte4::{Terminal, TerminalExt}; +use vte4::{Terminal, TerminalExt, TerminalExtManual}; const MAX_SCROLLBACK: u32 = 2000; @@ -10,6 +10,13 @@ pub struct TermWidget { pub term: Terminal, } +const ADW_LIGHT_FG: &str = "#000000"; +const ADW_DARK_FG: &str = "#ffffff"; +const ADW_PALETTE: [&str; 16] = [ + "#241f31", "#c01c28", "#2ec27e", "#f5c211", "#1e78e4", "#9841bb", "#0ab9dc", "#c0bfbc", + "#5e5c64", "#ed333b", "#57e389", "#f8e45c", "#51a1ff", "#c061cb", "#4fd2fd", "#f6f5f4", +]; + impl TermWidget { pub fn new() -> Self { let term = Terminal::builder() @@ -31,14 +38,21 @@ impl TermWidget { } pub fn set_color_scheme(&self) { - // TODO: use theme colors - if adw::StyleManager::default().is_dark() { - self.term - .set_color_foreground(&gdk::RGBA::new(1.0, 1.0, 1.0, 1.0)); + let fg = if adw::StyleManager::default().is_dark() { + ADW_DARK_FG } else { - self.term - .set_color_foreground(&gdk::RGBA::new(0.0, 0.0, 0.0, 1.0)); - } + ADW_LIGHT_FG + }; + let rgba_palette = ADW_PALETTE + .iter() + .map(|c| gdk::RGBA::parse(*c).unwrap()) + .collect::>(); + self.term.set_colors( + Some(&gdk::RGBA::parse(fg).unwrap()), + None, + // better way to convert to vec of references? + rgba_palette.iter().collect::>().as_slice(), + ); } pub fn feed(&self, txt: &str) {