Skip to content

Commit

Permalink
feat: add control panel (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
shamilsan authored Mar 21, 2024
1 parent 5dd4974 commit f59a702
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 17 deletions.
36 changes: 35 additions & 1 deletion examples/hello_world.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use leptos::*;
use leptos::{ev::keydown, *};
use leptos_use::use_event_listener;
use lerni::*;

#[component]
Expand All @@ -11,10 +12,43 @@ pub fn HelloWorld() -> impl IntoView {
<Slide background_color=Color::PaleGreen>
<Label>"← World!"</Label>
</Slide>
<Counter/>
</SlideShow>
}
}

#[component]
pub fn Counter() -> impl IntoView {
let (counter, set_counter) = create_signal(0);

let node_ref = create_node_ref();
_ = use_event_listener(document().body(), keydown, move |e| {
if is_active_slide(node_ref) {
if e.key() == "Enter" {
set_counter.set(counter.get() + 1);
} else if e.key() == "Escape" && counter.get() > 0 {
set_counter.set(counter.get() - 1);
}
}
});

create_effect(move |_| {
if let Some(el) = node_ref.get() {
let panel_item =
view! { <label class="label is-large">"Counter: " {move || counter.get()}</label> };
_ = el.on_mount(move |_| mount_on_panel(node_ref, panel_item));
}
});

view! {
<Slide node_ref=node_ref>
<Label>
"Counter (press 'Enter' and 'Escape' to change): " {move || counter.get()}
</Label>
</Slide>
}
}

#[wasm_bindgen(start)]
pub fn main() {
lerni::start(HelloWorld);
Expand Down
38 changes: 37 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use leptos::*;
use leptos::{html::Div, *};

/// Start function.
///
Expand Down Expand Up @@ -69,3 +69,39 @@ pub mod keys {
/// Digit 9 key.
pub const DIGIT_9: u32 = 57;
}

/// Check whether a slide is active.
pub fn is_active_slide(node_ref: NodeRef<Div>) -> bool {
if let Some(node) = node_ref.get() {
if let Some(parent) = node.parent_element() {
return parent.get_attribute("hidden").is_none();
}
}

false
}

/// Check whether a slide is visible.
pub fn slide_number(node_ref: NodeRef<Div>) -> Option<usize> {
if let Some(node) = node_ref.get_untracked() {
if let Some(parent) = node.parent_element() {
return parent.get_attribute("number").and_then(|n| n.parse().ok());
}
}

None
}

/// Mount a child view on a panel.
pub fn mount_on_panel(node_ref: NodeRef<Div>, item: impl IntoView) {
let panel_item_refs: Option<Vec<NodeRef<Div>>> = use_context();
if let Some(panel_item_refs) = panel_item_refs {
if let Some(n) = slide_number(node_ref) {
if let Some(panel_item_ref) = panel_item_refs.get(n) {
if let Some(el) = panel_item_ref.get_untracked() {
_ = el.child(item);
}
}
}
}
}
2 changes: 0 additions & 2 deletions src/widgets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ pub use text::Text;
/// Additional information provided to all slides.
#[derive(Clone, Copy, Default, Debug, PartialEq)]
pub struct Metadata {
/// Visibility flag.
pub visible: bool,
/// Teacher mode flag.
pub teacher_mode: bool,
/// Pointer on/off flag.
Expand Down
5 changes: 5 additions & 0 deletions src/widgets/slide.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use leptos::{
ev::{resize, MouseEvent},
html::Div,
svg::Svg,
*,
};
Expand All @@ -21,6 +22,7 @@ pub fn Slide(
#[prop(optional, into)] pointer: MaybeSignal<bool>,
#[prop(optional, into)] blur: MaybeSignal<bool>,
#[prop(default = 15)] blur_radius: i32,
#[prop(optional)] node_ref: Option<NodeRef<Div>>,
children: Children,
) -> impl IntoView {
let metadata = use_context::<Metadata>();
Expand Down Expand Up @@ -82,8 +84,11 @@ pub fn Slide(
Default::default()
};

let node_ref = node_ref.unwrap_or_else(create_node_ref);

view! {
<div
node_ref=node_ref
class="container pl-4 mt-4 pr-4"
style:max-width=move || {
if metadata.is_none() {
Expand Down
57 changes: 44 additions & 13 deletions src/widgets/slideshow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use leptos::{
};
use leptos_use::*;
use std::collections::BTreeSet;
use web_sys::MouseEvent;

use crate::Metadata;

Expand Down Expand Up @@ -39,22 +40,32 @@ pub fn SlideShow(
set_width.set(crate::calc_width(PAGINATION_WIDTH, CONTROL_PANEL_HEIGHT));
});

let mut metadata = Metadata {
let metadata = Metadata {
teacher_mode,
pointer,
..Default::default()
};
provide_context(metadata);

let mut panel_items = Vec::with_capacity(count);
let mut panel_item_refs = Vec::with_capacity(count);
let children = children
.into_iter()
.enumerate()
.map(|(i, child)| {
metadata.visible = i == page.get();
provide_context(metadata);
view! { <div hidden=move || i != page.get()>{child}</div> }
let panel_item_ref = create_node_ref();
panel_item_refs.push(panel_item_ref);
panel_items
.push(view! { <div node_ref=panel_item_ref hidden=move || i != page.get()></div> });
view! {
<div number=i hidden=move || i != page.get()>
{child}
</div>
}
})
.collect_view();

provide_context(panel_item_refs);

view! {
<div
class="container"
Expand All @@ -65,7 +76,9 @@ pub fn SlideShow(
>

<div class="columns is-gapless is-mobile">
<div class="column is-rest">{children} <ControlPanel/></div>
<div class="column is-rest">
{children} <ControlPanel>{panel_items}</ControlPanel>
</div>
<div class="pl-0 mt-4 pr-0" style:width="40px">
<Pagination page=page count=count/>
</div>
Expand All @@ -75,15 +88,25 @@ pub fn SlideShow(
}

#[component]
fn ControlPanel() -> impl IntoView {
fn ControlPanel(children: Children) -> impl IntoView {
view! {
<div class="container pl-4 mt-4 pr-4" style="max-width: 100%;">
<div class="buttons">
<button class="button is-rounded is-danger">
<span class="icon">
<i class="fas fa-lg fa-refresh"></i>
</span>
</button>
<div class="field is-grouped">
<p class="control">
<button class="button is-rounded is-link" on:click=history_back>
<span class="icon">
<i class="fas fa-lg fa-arrow-left"></i>
</span>
</button>
</p>
<p class="control">
<button class="button is-rounded is-danger">
<span class="icon">
<i class="fas fa-lg fa-refresh"></i>
</span>
</button>
</p>
{children()}
</div>
</div>
}
Expand Down Expand Up @@ -190,3 +213,11 @@ fn is_page_number_visible(index: usize, current: usize, count: usize) -> bool {
pages.contains(&index)
}
}

fn history_back(_event: MouseEvent) {
if let Some(window) = web_sys::window() {
if let Ok(history) = window.history() {
history.back().unwrap_or_default();
}
}
}

0 comments on commit f59a702

Please sign in to comment.