mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-08-07 16:49:01 +00:00
feat: wrap vte in its own struct to simplify the api
This commit is contained in:
parent
194e081c26
commit
2e7f6e701d
3 changed files with 87 additions and 46 deletions
|
@ -6,7 +6,9 @@ use gtk::glib::clone;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use relm4::prelude::*;
|
use relm4::prelude::*;
|
||||||
use relm4::{ComponentSender, SimpleComponent};
|
use relm4::{ComponentSender, SimpleComponent};
|
||||||
use zoha_vte4::{Terminal, TerminalExt};
|
use zoha_vte4::TerminalExt;
|
||||||
|
|
||||||
|
use super::term_widget::TermWidget;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SearchDirection {
|
pub enum SearchDirection {
|
||||||
|
@ -37,13 +39,11 @@ pub struct DebugView {
|
||||||
#[tracker::do_not_track]
|
#[tracker::do_not_track]
|
||||||
log_level: LogLevel,
|
log_level: LogLevel,
|
||||||
#[tracker::do_not_track]
|
#[tracker::do_not_track]
|
||||||
vte_terminal: Terminal,
|
term: TermWidget,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DebugViewInit {}
|
pub struct DebugViewInit {}
|
||||||
|
|
||||||
const MAX_SCROLLBACK: u32 = 2000;
|
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
impl SimpleComponent for DebugView {
|
impl SimpleComponent for DebugView {
|
||||||
type Init = DebugViewInit;
|
type Init = DebugViewInit;
|
||||||
|
@ -115,16 +115,11 @@ impl SimpleComponent for DebugView {
|
||||||
},
|
},
|
||||||
connect_entry: &search_entry,
|
connect_entry: &search_entry,
|
||||||
},
|
},
|
||||||
#[wrap(Some)]
|
set_content: Some(&model.term.container),
|
||||||
set_content: sw = >k::ScrolledWindow {
|
|
||||||
set_hexpand: true,
|
|
||||||
set_vexpand: true,
|
|
||||||
model.vte_terminal.clone(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self>) {
|
||||||
self.reset();
|
self.reset();
|
||||||
|
|
||||||
match message {
|
match message {
|
||||||
|
@ -142,19 +137,17 @@ impl SimpleComponent for DebugView {
|
||||||
let search_entry = self.search_entry.as_ref().unwrap().clone();
|
let search_entry = self.search_entry.as_ref().unwrap().clone();
|
||||||
let search_text = search_entry.text().to_string();
|
let search_text = search_entry.text().to_string();
|
||||||
if searchbar.is_search_mode() && !search_text.is_empty() {
|
if searchbar.is_search_mode() && !search_text.is_empty() {
|
||||||
if let Ok(regex) = zoha_vte4::Regex::for_search(&search_text, 0) {
|
self.term.set_search_term(Some(&search_text));
|
||||||
self.vte_terminal.search_set_regex(Some(®ex), 0);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
self.vte_terminal.search_set_regex(None, 0);
|
self.term.set_search_term(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Input::SearchFindMatch(direction) => match direction {
|
Self::Input::SearchFindMatch(direction) => match direction {
|
||||||
SearchDirection::Forward => {
|
SearchDirection::Forward => {
|
||||||
self.vte_terminal.search_find_next();
|
self.term.search_next();
|
||||||
}
|
}
|
||||||
SearchDirection::Backward => {
|
SearchDirection::Backward => {
|
||||||
self.vte_terminal.search_find_previous();
|
self.term.search_prev();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Self::Input::LogUpdated(n_log) => {
|
Self::Input::LogUpdated(n_log) => {
|
||||||
|
@ -173,15 +166,15 @@ impl SimpleComponent for DebugView {
|
||||||
None => Some(row),
|
None => Some(row),
|
||||||
};
|
};
|
||||||
if let Some(t) = txt {
|
if let Some(t) = txt {
|
||||||
self.vte_terminal.feed(t.as_bytes())
|
self.term.feed(&t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Input::ClearLog => {
|
Self::Input::ClearLog => {
|
||||||
self.vte_terminal.feed("\x1bc".as_bytes());
|
self.term.clear();
|
||||||
}
|
}
|
||||||
Self::Input::SetColorScheme => {
|
Self::Input::SetColorScheme => {
|
||||||
Self::set_color_scheme(&self.vte_terminal);
|
self.term.set_color_scheme();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,24 +216,13 @@ impl SimpleComponent for DebugView {
|
||||||
search_entry: None,
|
search_entry: None,
|
||||||
dropdown: None,
|
dropdown: None,
|
||||||
log_level: LogLevel::Trace,
|
log_level: LogLevel::Trace,
|
||||||
vte_terminal: {
|
term: TermWidget::new(),
|
||||||
let t = Terminal::builder()
|
|
||||||
.scroll_on_output(true)
|
|
||||||
.scrollback_lines(MAX_SCROLLBACK)
|
|
||||||
.scroll_unit_is_pixels(true)
|
|
||||||
.vexpand(true)
|
|
||||||
.hexpand(true)
|
|
||||||
.build();
|
|
||||||
t.set_clear_background(false);
|
|
||||||
t.search_set_wrap_around(true);
|
|
||||||
Self::set_color_scheme(&t);
|
|
||||||
t
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
model.term.set_color_scheme();
|
||||||
|
|
||||||
{
|
{
|
||||||
let sc = gtk::ShortcutController::new();
|
let sc = gtk::ShortcutController::new();
|
||||||
let term = model.vte_terminal.clone();
|
let term = model.term.term.clone();
|
||||||
sc.add_shortcut(gtk::Shortcut::new(
|
sc.add_shortcut(gtk::Shortcut::new(
|
||||||
gtk::ShortcutTrigger::parse_string("<Control>c"),
|
gtk::ShortcutTrigger::parse_string("<Control>c"),
|
||||||
Some(gtk::CallbackAction::new(move |_, _| {
|
Some(gtk::CallbackAction::new(move |_, _| {
|
||||||
|
@ -250,7 +232,7 @@ impl SimpleComponent for DebugView {
|
||||||
true
|
true
|
||||||
})),
|
})),
|
||||||
));
|
));
|
||||||
let term = model.vte_terminal.clone();
|
let term = model.term.term.clone();
|
||||||
sc.add_shortcut(gtk::Shortcut::new(
|
sc.add_shortcut(gtk::Shortcut::new(
|
||||||
gtk::ShortcutTrigger::parse_string("<Control>a"),
|
gtk::ShortcutTrigger::parse_string("<Control>a"),
|
||||||
Some(gtk::CallbackAction::new(move |_, _| {
|
Some(gtk::CallbackAction::new(move |_, _| {
|
||||||
|
@ -258,7 +240,7 @@ impl SimpleComponent for DebugView {
|
||||||
true
|
true
|
||||||
})),
|
})),
|
||||||
));
|
));
|
||||||
model.vte_terminal.add_controller(sc);
|
model.term.term.add_controller(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
@ -269,13 +251,3 @@ impl SimpleComponent for DebugView {
|
||||||
ComponentParts { model, widgets }
|
ComponentParts { model, widgets }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DebugView {
|
|
||||||
fn set_color_scheme(term: &Terminal) {
|
|
||||||
if adw::StyleManager::default().is_dark() {
|
|
||||||
term.set_color_foreground(>k::gdk::RGBA::new(1.0, 1.0, 1.0, 1.0));
|
|
||||||
} else {
|
|
||||||
term.set_color_foreground(>k::gdk::RGBA::new(0.0, 0.0, 0.0, 1.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,5 +15,6 @@ pub mod preference_rows;
|
||||||
pub mod profile_editor;
|
pub mod profile_editor;
|
||||||
pub mod steam_launch_options_box;
|
pub mod steam_launch_options_box;
|
||||||
mod steamvr_calibration_box;
|
mod steamvr_calibration_box;
|
||||||
|
pub mod term_widget;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
pub mod wivrn_conf_editor;
|
pub mod wivrn_conf_editor;
|
||||||
|
|
68
src/ui/term_widget.rs
Normal file
68
src/ui/term_widget.rs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
use gtk4::gdk;
|
||||||
|
use relm4::adw;
|
||||||
|
use zoha_vte4::{Terminal, TerminalExt};
|
||||||
|
|
||||||
|
const MAX_SCROLLBACK: u32 = 2000;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct TermWidget {
|
||||||
|
pub container: gtk4::ScrolledWindow,
|
||||||
|
pub term: Terminal,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TermWidget {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let term = Terminal::builder()
|
||||||
|
.scroll_on_output(true)
|
||||||
|
.scrollback_lines(MAX_SCROLLBACK)
|
||||||
|
.scroll_unit_is_pixels(true)
|
||||||
|
.vexpand(true)
|
||||||
|
.hexpand(true)
|
||||||
|
.build();
|
||||||
|
term.set_clear_background(false);
|
||||||
|
term.search_set_wrap_around(true);
|
||||||
|
let container = gtk4::ScrolledWindow::builder()
|
||||||
|
.hexpand(true)
|
||||||
|
.vexpand(true)
|
||||||
|
.child(&term)
|
||||||
|
.build();
|
||||||
|
let this = Self { container, term };
|
||||||
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
} else {
|
||||||
|
self.term
|
||||||
|
.set_color_foreground(&gdk::RGBA::new(0.0, 0.0, 0.0, 1.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn feed(&self, txt: &str) {
|
||||||
|
self.term.feed(txt.replace('\n', "\r\n").as_bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&self) {
|
||||||
|
self.term.feed("\x1bc".as_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_search_term(&self, term: Option<&str>) {
|
||||||
|
self.term.search_set_regex(
|
||||||
|
term.map(|txt| zoha_vte4::Regex::for_search(txt, 0).ok())
|
||||||
|
.flatten()
|
||||||
|
.as_ref(),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn search_next(&self) {
|
||||||
|
self.term.search_find_next();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn search_prev(&self) {
|
||||||
|
self.term.search_find_previous();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue