lesavka/client/src/launcher/ui_runtime/report_popouts.rs

257 lines
7.7 KiB
Rust

pub fn open_session_log_popout(
app: &gtk::Application,
handle: &Rc<RefCell<Option<gtk::ApplicationWindow>>>,
buffer: &gtk::TextBuffer,
) {
open_text_buffer_popout(
app,
handle,
None,
buffer,
"Lesavka Log",
"Copy",
gtk::WrapMode::WordChar,
);
}
pub fn open_diagnostics_popout(
app: &gtk::Application,
handle: &Rc<RefCell<Option<gtk::ApplicationWindow>>>,
label_handle: &Rc<RefCell<Option<gtk::Label>>>,
scroll_handle: &Rc<RefCell<Option<gtk::ScrolledWindow>>>,
rendered_text: &Rc<RefCell<String>>,
) {
if let Some(window) = handle.borrow().as_ref() {
window.present();
return;
}
let window = gtk::ApplicationWindow::builder()
.application(app)
.title("Lesavka Diagnostics")
.default_width(980)
.default_height(680)
.build();
super::ui_components::install_css(&window);
super::ui_components::install_window_icon(&window);
super::ui_components::install_window_chrome(&window, "Lesavka Diagnostics");
let root = gtk::Box::new(gtk::Orientation::Vertical, 10);
root.set_margin_start(14);
root.set_margin_end(14);
root.set_margin_top(14);
root.set_margin_bottom(14);
let toolbar = gtk::Box::new(gtk::Orientation::Horizontal, 8);
let copy_button = gtk::Button::with_label("Copy Report");
toolbar.append(&copy_button);
root.append(&toolbar);
let current_text = rendered_text.borrow().clone();
let label = gtk::Label::new(Some(&current_text));
label.add_css_class("status-log");
label.set_selectable(true);
label.set_xalign(0.0);
label.set_yalign(0.0);
label.set_wrap(false);
label.set_halign(gtk::Align::Start);
label.set_valign(gtk::Align::Start);
label.set_hexpand(true);
let shell = gtk::Box::new(gtk::Orientation::Vertical, 0);
shell.set_hexpand(true);
shell.set_vexpand(false);
shell.append(&label);
let scroll = gtk::ScrolledWindow::builder()
.hexpand(true)
.vexpand(true)
.child(&shell)
.build();
*label_handle.borrow_mut() = Some(label.clone());
*scroll_handle.borrow_mut() = Some(scroll.clone());
root.append(&scroll);
window.set_child(Some(&root));
window.maximize();
{
let rendered_text = Rc::clone(rendered_text);
copy_button.connect_clicked(move |_| {
let current_text = rendered_text.borrow().clone();
let _ = copy_plain_text(&current_text);
});
}
{
let handle = Rc::clone(handle);
let label_handle = Rc::clone(label_handle);
let scroll_handle = Rc::clone(scroll_handle);
window.connect_close_request(move |_| {
handle.borrow_mut().take();
label_handle.borrow_mut().take();
scroll_handle.borrow_mut().take();
glib::Propagation::Proceed
});
}
*handle.borrow_mut() = Some(window.clone());
window.present();
}
fn open_text_buffer_popout(
app: &gtk::Application,
handle: &Rc<RefCell<Option<gtk::ApplicationWindow>>>,
scroll_handle: Option<&Rc<RefCell<Option<gtk::ScrolledWindow>>>>,
buffer: &gtk::TextBuffer,
title: &str,
copy_button_label: &str,
wrap_mode: gtk::WrapMode,
) {
if let Some(window) = handle.borrow().as_ref() {
window.present();
return;
}
let window = gtk::ApplicationWindow::builder()
.application(app)
.title(title)
.default_width(980)
.default_height(680)
.build();
super::ui_components::install_css(&window);
super::ui_components::install_window_icon(&window);
super::ui_components::install_window_chrome(&window, title);
let root = gtk::Box::new(gtk::Orientation::Vertical, 10);
root.set_margin_start(14);
root.set_margin_end(14);
root.set_margin_top(14);
root.set_margin_bottom(14);
let toolbar = gtk::Box::new(gtk::Orientation::Horizontal, 8);
let copy_button = gtk::Button::with_label(copy_button_label);
toolbar.append(&copy_button);
root.append(&toolbar);
let view = gtk::TextView::with_buffer(buffer);
view.add_css_class("status-log");
view.set_editable(false);
view.set_cursor_visible(false);
view.set_monospace(true);
view.set_wrap_mode(wrap_mode);
let scroll = gtk::ScrolledWindow::builder()
.hexpand(true)
.vexpand(true)
.child(&view)
.build();
if let Some(scroll_handle) = scroll_handle {
*scroll_handle.borrow_mut() = Some(scroll.clone());
}
root.append(&scroll);
window.set_child(Some(&root));
window.maximize();
{
let buffer = buffer.clone();
copy_button.connect_clicked(move |_| {
let _ = copy_session_log(&buffer);
});
}
{
let handle = Rc::clone(handle);
let scroll_handle = scroll_handle.cloned();
window.connect_close_request(move |_| {
handle.borrow_mut().take();
if let Some(scroll_handle) = &scroll_handle {
scroll_handle.borrow_mut().take();
}
glib::Propagation::Proceed
});
}
*handle.borrow_mut() = Some(window.clone());
window.present();
}
pub fn stop_child_process(child_proc: &Rc<RefCell<Option<RelayChild>>>) {
if let Some(mut child) = child_proc.borrow_mut().take() {
let _ = child.kill();
let _ = child.wait();
}
}
pub fn shutdown_launcher_runtime(
child_proc: &Rc<RefCell<Option<RelayChild>>>,
tests: &Rc<RefCell<DeviceTestController>>,
preview: Option<&LauncherPreview>,
widgets: &LauncherWidgets,
popouts: &Rc<RefCell<[Option<PopoutWindowHandle>; 2]>>,
diagnostics_popout: &Rc<RefCell<Option<gtk::ApplicationWindow>>>,
log_popout: &Rc<RefCell<Option<gtk::ApplicationWindow>>>,
) {
stop_child_process(child_proc);
tests.borrow_mut().stop_all();
if let Some(preview) = preview {
preview.set_session_active(false);
preview.shutdown_all();
}
for pane in &widgets.display_panes {
if let Some(binding) = pane.preview_binding.borrow_mut().take() {
binding.close();
}
pane.picture.set_paintable(Option::<&gdk::Paintable>::None);
pane.stream_status.set_text("");
}
let mut detached_popouts = Vec::new();
{
let mut slots = popouts.borrow_mut();
for slot in slots.iter_mut() {
if let Some(handle) = slot.take() {
detached_popouts.push(handle);
}
}
}
for handle in detached_popouts {
handle.binding.close();
handle
.picture
.set_paintable(Option::<&gdk::Paintable>::None);
handle.window.set_child(Option::<&gtk::Widget>::None);
handle.window.hide();
}
if let Some(window) = diagnostics_popout.borrow_mut().take() {
widgets.diagnostics_popout_label.borrow_mut().take();
widgets.diagnostics_popout_scroll.borrow_mut().take();
window.set_child(Option::<&gtk::Widget>::None);
window.hide();
}
if let Some(window) = log_popout.borrow_mut().take() {
window.set_child(Option::<&gtk::Widget>::None);
window.hide();
}
}
pub fn reap_exited_child(child_proc: &Rc<RefCell<Option<RelayChild>>>) -> bool {
let mut slot = child_proc.borrow_mut();
match slot.as_mut() {
Some(child) => match child.try_wait() {
Ok(Some(_)) => {
*slot = None;
false
}
Ok(None) | Err(_) => true,
},
None => false,
}
}
pub fn next_input_routing(routing: InputRouting) -> InputRouting {
match routing {
InputRouting::Remote => InputRouting::Local,
InputRouting::Local => InputRouting::Remote,
}
}