use gdk::{gio::SimpleAction, prelude::ActionMapExt};
use grx_macros::component;
use gtk::gdk;
use gtk::traits::GtkApplicationExt;
use std::{collections::LinkedList, rc::Rc};
use crate::{
action_row, clamp, container, grx, header_bar,
list::{self, List},
props, scroll, text, window, ContainerExt, Text, Textual,
};
type PushFn = Box<dyn Fn(&dyn std::fmt::Debug, &dyn std::fmt::Debug) + 'static>;
thread_local! {
static PUSH: std::cell::RefCell<Option<PushFn>> = Default::default();
}
pub fn gstore_debug_window(app: &libadwaita::Application) -> Rc<GstoreDebug> {
let d = gstore_debug(Default::default());
let action = SimpleAction::new("gstore-debug", None);
let debug_window = d.clone();
action.connect_activate(move |_, _| debug_window.show());
app.set_accels_for_action("app.gstore-debug", &["<Shift><Alt>G"]);
app.add_action(&action);
let debug_window = d.clone();
PUSH.with(|c| {
let mut c = c.borrow_mut();
*c = Some(Box::new(move |action, state| {
debug_window.update(action, state)
}));
});
d
}
pub fn send_state_update(action: &dyn std::fmt::Debug, state: &dyn std::fmt::Debug) {
PUSH.with(|c| {
if let Some(p) = &*c.borrow() {
p(action, state);
}
})
}
#[props]
#[derive(Default, Debug)]
pub struct Props {}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct State {
actions: LinkedList<String>,
state: String,
}
#[component(Props, State)]
#[derive(Debug)]
pub struct GstoreDebug {}
pub fn gstore_debug(props: Props) -> Rc<GstoreDebug> {
let action_list: Rc<List>;
let text: Rc<Text>;
let comp = grx! {
window (styles=[w(600), h(800)]) [
container (styles=[vertical]) [
header_bar (title=Some("gstore debugging".into())),
container (styles=[vexpand]) [
scroll (styles=[vexpand]) [
clamp (styles=[m(4)]) [
list (
id=action_list,
classes="boxed-list".into(),
styles=[valign(start), hexpand, vexpand])
]
],
container (styles=[w(400)]) [
scroll [
container (styles=[hexpand, vexpand]) [
text(id=text)
]
]
]
]
]
]
};
let comp = GstoreDebug::new(props, comp);
comp.on_state(move |s| {
text.set_text(&s.state);
action_list.clear();
for action in s.actions.iter() {
action_list.append(grx! {
action_row(title=action.clone())
});
}
});
comp
}
impl GstoreDebug {
pub fn show(self: &Rc<Self>) {
let window: Rc<window::Window> = self.root.clone().into_any().downcast().unwrap();
window.show();
}
pub fn update(self: &Rc<Self>, action: &dyn std::fmt::Debug, state: &dyn std::fmt::Debug) {
let action = format!("{:?}", action);
let state = format!("{:#?}", state);
self.set_state(move |s| {
s.state = state.clone();
s.actions.push_front(action.clone())
});
}
}