Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: modal draft #19

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions examples/widget-gallery/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ rust-version = "1.75"

[dependencies]
im = "15.1.0"
oxytail-theme-dark = "0.1.1"
oxytail-base = "0.1.1"
floem = "0.1.1"
oxytail-theme-dark = { path = "../../oxytail-theme-dark" }
oxytail-base = { path = "../../oxytail-base" }
floem = "0.1.1"
5 changes: 4 additions & 1 deletion examples/widget-gallery/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use floem::{

use headers::headers_sizes;
use inputs::{text_input_sizes, text_input_variants};
use modals::modal_demo;
use oxytail_base::{
init_theme,
widgets::{button::button, text_divider::text_divider, text_header::text_header},
Expand All @@ -34,6 +35,7 @@ mod btn;
mod checkboxes;
pub mod headers;
mod inputs;
pub mod modals;
mod radio_buttons;
mod toggles;
pub mod tooltips;
Expand All @@ -44,7 +46,7 @@ fn padded_container_box(child: impl View + 'static) -> ContainerBox {

fn app_view() -> impl View {
let tabs: im::Vector<&str> = vec![
"Intro", "Header", "Button", "Radio", "Checkbox", "Input", "Tooltip", "Toggle",
"Intro", "Header", "Button", "Radio", "Checkbox", "Modal", "Input", "Tooltip", "Toggle",
]
.into_iter()
.collect();
Expand Down Expand Up @@ -172,6 +174,7 @@ fn app_view() -> impl View {
labeled_checkboxes(),
))),
"Input" => padded_container_box(v_stack((text_input_variants(), text_input_sizes()))),
"Modal" => padded_container_box(modal_demo()),
"Tooltip" => padded_container_box(v_stack((
text_header("Tooltips", None),
text_divider(),
Expand Down
21 changes: 21 additions & 0 deletions examples/widget-gallery/src/modals.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use floem::{
reactive::create_signal,
view::View,
views::{label, v_stack, Decorators},
EventPropagation,
};
use oxytail_base::widgets::{button::button, modal::modal};

pub fn modal_demo() -> impl View {
let (open, set_open) = create_signal(true);

v_stack((
button(|| "open modal", None).on_click(move |_| {
println!("clicked");
set_open.update(|open| *open = !*open);

EventPropagation::Stop
}),
modal(label(|| "modal content"), open),
))
}
39 changes: 37 additions & 2 deletions oxytail-base/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,51 @@
pub mod themes;
pub mod widgets;

use std::sync::OnceLock;
use std::{any::Any, sync::OnceLock};

use floem::{
reactive::ReadSignal,
view::View,
views::{container, label, v_stack},
};
use themes::ThemeStyling;
use widgets::modal::modal;

pub static GLOBAL_THEME: OnceLock<Box<dyn ThemeStyling + Send + Sync>> = OnceLock::new();
// App head. We need a global reference to it, to render topmost level stuff.
pub static TOPMOST_HOOK: OnceLock<Box<dyn View + Send + Sync>> = OnceLock::new();

pub(crate) fn get_current_theme() -> &'static Box<dyn ThemeStyling + Send + Sync> {
GLOBAL_THEME.get().expect("Oxytail widget received no theme while trying to render. Did you forget to run `init_theme(theme)`")
GLOBAL_THEME.get().expect("Oxytail widget received no theme while trying to render. Did you forget to run `init_oxytail(theme, root_component)`")
}

pub(crate) fn get_current_topmost() -> &'static Box<dyn View + Send + Sync> {
TOPMOST_HOOK.get().expect("Oxytail widget received no root_component while trying to render. Did you forget to run `init_oxytail(theme, root_component)`")
}

pub fn init_theme(theme: impl ThemeStyling + Send + Sync + 'static) {
GLOBAL_THEME.get_or_init(|| Box::new(theme));
}

pub fn init_topmost_hook(
topmost: impl View + Send + Sync + 'static,
) -> impl View + Send + Sync + 'static {
TOPMOST_HOOK.get_or_init(|| Box::new(topmost));
topmost
}

pub fn init_oxytail(
theme: impl ThemeStyling + Send + Sync + 'static,
topmost: impl View + Send + Sync + 'static,
) -> impl View {
init_theme(theme);
init_topmost_hook(topmost);
topmost
}

pub fn mut_topmost_hook() {}

pub fn oxytail_wrapper<V: View + 'static>(child: V) -> impl View {
let modall = label(|| "ASd");
v_stack((modall, child))
}
3 changes: 3 additions & 0 deletions oxytail-base/src/themes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,7 @@ pub trait ThemeStyling {

/// Defines how a `tooltip` should look like.
fn get_tooltip_style(&self, tooltip_props: TooltipProps) -> Box<dyn Fn(Style) -> Style + '_>;

/// Defined how a `modal` should look like. Only applies when the modal is open, otherwise it's Display::None
fn get_modal_style(&self, open: bool) -> Box<dyn Fn(Style) -> Style + '_>;
}
1 change: 1 addition & 0 deletions oxytail-base/src/widgets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ pub mod radio_button;
pub mod text_header;
pub mod text_divider;
pub mod tooltip;
pub mod modal;
45 changes: 45 additions & 0 deletions oxytail-base/src/widgets/modal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use std::fmt::Display;

use floem::{
action::set_window_title,
peniko::Color,
reactive::{ReadSignal, RwSignal},
style::{Position, Style},
view::View,
views::{container, empty, Decorators},
window,
};

use crate::get_current_theme;

use super::common_props::{OxySize, OxyVariant};

#[derive(Default, Clone, Copy)]
pub struct ModalProps {
pub open: bool,
}

pub fn modal<V: View + 'static>(content: V, open: ReadSignal<bool>) -> impl View {
let base_widget = container(content);
let theme = get_current_theme();

// let props = props.unwrap_or(ModalProps::default());

let styles_enhancer = theme.get_modal_style(open.get());

let styled_modal = base_widget.style(move |s| styles_enhancer(s));
let styled_modal = styled_modal.style(move |s| {
s.display(floem::style::Display::None)
.apply_if(open.get(), |s| {
s.display(floem::style::Display::Flex)
.position(Position::Absolute)
.inset_top(0)
.inset_left(0)
.margin_left(-50)
.z_index(9999999)
.background(Color::WHITE)
})
});

styled_modal
}
6 changes: 4 additions & 2 deletions oxytail-theme-dark/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ rust-version = "1.75"

[dependencies]
floem = "0.1.1"
oxytail-base = "0.1.1"
oxytail-theme-defaults = "0.1.1"
oxytail-base = { path = "../oxytail-base" }
# oxytail-base = "0.1.1"
oxytail-theme-defaults = { path = "../oxytail-theme-defaults" }
# oxytail-theme-defaults = "0.1.1"
4 changes: 4 additions & 0 deletions oxytail-theme-dark/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,8 @@ impl ThemeStyling for Theme {
self.theme_defaults(),
)
}

fn get_modal_style(&self, open: bool) -> Box<dyn Fn(Style) -> Style + '_> {
oxytail_theme_defaults::ThemeDefault::get_modal_style(open)
}
}
3 changes: 2 additions & 1 deletion oxytail-theme-defaults/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ rust-version = "1.75"

[dependencies]
floem = "0.1.1"
oxytail-base = "0.1.1"
# oxytail-base = "0.1.1"
oxytail-base = { path = "../oxytail-base" }
9 changes: 9 additions & 0 deletions oxytail-theme-defaults/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,13 @@ impl ThemeDefault {

Box::new(styles_creator)
}

pub fn get_modal_style(open: bool) -> Box<dyn Fn(Style) -> Style> {
let styles_creator = move |s: Style| {
let base_style = s.padding(8.);

base_style
};
Box::new(styles_creator)
}
}