Skip to content

Commit

Permalink
examples: fix/update GTK example, and remove web parallels (#2839)
Browse files Browse the repository at this point in the history
  • Loading branch information
gbj authored and chrisp60 committed Aug 15, 2024
1 parent b48a263 commit 36df797
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 140 deletions.
16 changes: 8 additions & 8 deletions examples/gtk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ version = "0.1.0"
edition = "2021"

[dependencies]
leptos = { path = "../../leptos", features = ["csr"] }
leptos = { path = "../../leptos" }
throw_error = { path = "../../any_error/" }
any_spawner = { path = "../../any_spawner/" }

# these are used to build the integration
gtk = { version = "0.9.0", package = "gtk4" }
next_tuple = { path = "../../next_tuple/" }
gtk = { version = "0.9.0", package = "gtk4", optional = true }
paste = "1.0"

console_error_panic_hook = { version = "0.1.7", optional = true }

[features]
gtk = ["dep:gtk", "any_spawner/glib"]
wasm = ["any_spawner/wasm-bindgen", "dep:console_error_panic_hook"]
# we want to support using glib for the reactive runtime event loop
any_spawner = { path = "../../any_spawner/", features = ["glib"] }
# yes, we want effects to run: this is a "frontend," not a backend
reactive_graph = { path = "../../reactive_graph", features = ["effects"] }
26 changes: 10 additions & 16 deletions examples/gtk/src/leptos_gtk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ impl Mountable<LeptosGtk> for Element {
.insert_before(&parent.0, marker.as_ref().map(|m| &m.0));
}

fn insert_before_this(&self,
child: &mut dyn Mountable<LeptosGtk>,
) -> bool {
child.mount(parent, Some(self.as_ref()));
true
fn insert_before_this(&self, child: &mut dyn Mountable<LeptosGtk>) -> bool {
if let Some(parent) = self.0.parent() {
child.mount(&Element(parent), Some(self));
return true;
}
false
}
}

Expand All @@ -79,11 +80,8 @@ impl Mountable<LeptosGtk> for Text {
.insert_before(&parent.0, marker.as_ref().map(|m| &m.0));
}

fn insert_before_this(&self,
child: &mut dyn Mountable<LeptosGtk>,
) -> bool {
child.mount(parent, Some(self.as_ref()));
true
fn insert_before_this(&self, child: &mut dyn Mountable<LeptosGtk>) -> bool {
self.0.insert_before_this(child)
}
}

Expand Down Expand Up @@ -332,16 +330,12 @@ where
parent: &<LeptosGtk as Renderer>::Element,
marker: Option<&<LeptosGtk as Renderer>::Node>,
) {
println!("mounting {}", std::any::type_name::<Widg>());
self.children.mount(&self.widget, None);
LeptosGtk::insert_node(parent, &self.widget, marker);
}

fn insert_before_this(&self,
child: &mut dyn Mountable<LeptosGtk>,
) -> bool {
child.mount(parent, Some(self.widget.as_ref()));
true
fn insert_before_this(&self, child: &mut dyn Mountable<LeptosGtk>) -> bool {
self.widget.insert_before_this(child)
}
}

Expand Down
164 changes: 48 additions & 116 deletions examples/gtk/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,88 +1,59 @@
#[cfg(feature = "gtk")]
use gtk::{
glib::Value, prelude::*, Application, ApplicationWindow, Orientation,
Widget,
};
#[cfg(feature = "wasm")]
use leptos::tachys::{dom::body, html::element, html::event as ev};
use leptos::{
logging,
prelude::*,
reactive_graph::{effect::Effect, owner::Owner, signal::RwSignal},
Executor, For, ForProps,
};
#[cfg(feature = "gtk")]
use leptos_gtk::{Element, LGtkWidget, LeptosGtk};
use any_spawner::Executor;
use gtk::{prelude::*, Application, ApplicationWindow, Orientation};
use leptos::prelude::*;
use leptos_gtk::LeptosGtk;
use std::{mem, thread, time::Duration};
#[cfg(feature = "gtk")]
mod leptos_gtk;

const APP_ID: &str = "dev.leptos.Counter";

// Basic GTK app setup from https://gtk-rs.org/gtk4-rs/stable/latest/book/hello_world.html
fn main() {
// use the glib event loop to power the reactive system
#[cfg(feature = "gtk")]
{
_ = Executor::init_glib();
let app = Application::builder().application_id(APP_ID).build();

app.connect_startup(|_| load_css());

app.connect_activate(|app| {
// Connect to "activate" signal of `app`
let owner = Owner::new();
let view = owner.with(ui);
let (root, state) = leptos_gtk::root(view);

let window = ApplicationWindow::builder()
.application(app)
.title("TachyGTK")
.child(&root)
.build();
// Present window
window.present();
mem::forget((owner, state));
});

app.run();
}

#[cfg(all(feature = "wasm", not(feature = "gtk")))]
{
console_error_panic_hook::set_once();
_ = Executor::init_wasm_bindgen();
_ = Executor::init_glib();
let app = Application::builder().application_id(APP_ID).build();

app.connect_startup(|_| load_css());

app.connect_activate(|app| {
// Connect to "activate" signal of `app`
let owner = Owner::new();
let view = owner.with(ui);
let mut state = view.build();
state.mount(&body().into(), None);
let (root, state) = leptos_gtk::root(view);

let window = ApplicationWindow::builder()
.application(app)
.title("TachyGTK")
.child(&root)
.build();
// Present window
window.present();
mem::forget((owner, state));
}
}
});

#[cfg(feature = "gtk")]
type Rndr = LeptosGtk;
#[cfg(all(feature = "wasm", not(feature = "gtk")))]
type Rndr = Dom;
app.run();
}

fn ui() -> impl Render<Rndr> {
fn ui() -> impl Render<LeptosGtk> {
let value = RwSignal::new(0);
let rows = RwSignal::new(vec![1, 2, 3, 4, 5]);

Effect::new(move |_| {
logging::log!("value = {}", value.get());
println!("value = {}", value.get());
});

// just an example of multithreaded reactivity
#[cfg(feature = "gtk")]
thread::spawn(move || loop {
thread::sleep(Duration::from_millis(250));
value.update(|n| *n += 1);
});

vstack((
hstack((
button("-1", move || value.update(|n| *n -= 1)),
button("-1", move || {
println!("clicked -1");
value.update(|n| *n -= 1);
}),
move || value.get().to_string(),
button("+1", move || value.update(|n| *n += 1)),
)),
Expand All @@ -91,75 +62,36 @@ fn ui() -> impl Render<Rndr> {
items.swap(1, 3);
})
}),
hstack(For(ForProps::builder()
.each(move || rows.get())
.key(|k| *k)
.children(|v| v)
.build())),
hstack(rows),
))
}

fn button(
label: impl Render<Rndr>,
label: impl Render<LeptosGtk>,
callback: impl Fn() + Send + Sync + 'static,
) -> impl Render<Rndr> {
#[cfg(feature = "gtk")]
{
leptos_gtk::button()
.child(label)
.connect("clicked", move |_| {
callback();
None
})
}
#[cfg(all(feature = "wasm", not(feature = "gtk")))]
{
element::button()
.on(ev::click, move |_| callback())
.child(label)
}
) -> impl Render<LeptosGtk> {
leptos_gtk::button()
.child(label)
.connect("clicked", move |_| {
callback();
None
})
}

fn vstack(children: impl Render<Rndr>) -> impl Render<Rndr> {
#[cfg(feature = "gtk")]
{
leptos_gtk::r#box()
.orientation(Orientation::Vertical)
.spacing(12)
.child(children)
}
#[cfg(all(feature = "wasm", not(feature = "gtk")))]
{
element::div()
.style(("display", "flex"))
.style(("flex-direction", "column"))
.style(("align-items", "center"))
.style(("justify-content", "center"))
.style(("margin", "1rem"))
.child(children)
}
fn vstack(children: impl Render<LeptosGtk>) -> impl Render<LeptosGtk> {
leptos_gtk::r#box()
.orientation(Orientation::Vertical)
.spacing(12)
.child(children)
}

fn hstack(children: impl Render<Rndr>) -> impl Render<Rndr> {
#[cfg(feature = "gtk")]
{
leptos_gtk::r#box()
.orientation(Orientation::Horizontal)
.spacing(12)
.child(children)
}
#[cfg(all(feature = "wasm", not(feature = "gtk")))]
{
element::div()
.style(("display", "flex"))
.style(("align-items", "center"))
.style(("justify-content", "center"))
.style(("margin", "1rem"))
.child(children)
}
fn hstack(children: impl Render<LeptosGtk>) -> impl Render<LeptosGtk> {
leptos_gtk::r#box()
.orientation(Orientation::Horizontal)
.spacing(12)
.child(children)
}

#[cfg(feature = "gtk")]
fn load_css() {
use gtk::{gdk::Display, CssProvider};

Expand Down

0 comments on commit 36df797

Please sign in to comment.