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: progress #22

Draft
wants to merge 2 commits 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: 5 additions & 1 deletion examples/widget-gallery/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use oxytail_base::{
widgets::{button::button, text_divider::text_divider, text_header::text_header},
};
use oxytail_theme_dark::Theme;
use progresses::progresses_variants;
use radio_buttons::{
disabled_labeled_radio_variants, labeled_radio_variants, radio_sizes, radio_variants,
};
Expand All @@ -36,6 +37,7 @@ mod btn;
mod checkboxes;
pub mod headers;
mod inputs;
pub mod progresses;
mod radio_buttons;
mod toggles;
pub mod tooltips;
Expand All @@ -46,7 +48,8 @@ fn padded_container_box(child: impl View + 'static) -> ContainerBox {

fn app_view() -> impl View {
let tabs: im::Vector<&str> = vec![
"Intro", "Header", "Button", "Badge", "Radio", "Checkbox", "Input", "Tooltip", "Toggle",
"Intro", "Header", "Button", "Badge", "Progress", "Radio", "Checkbox", "Input", "Tooltip",
"Toggle",
]
.into_iter()
.collect();
Expand Down Expand Up @@ -171,6 +174,7 @@ fn app_view() -> impl View {
text_divider(),badges_variants(), text_header("Sizes", None),
text_divider(), badges_sizes(), text_header("Outlines", None),
text_divider(), badges_outlines()))),
"Progress" => padded_container_box(progresses_variants()),
"Radio" => padded_container_box(v_stack((radio_variants(),radio_sizes(),labeled_radio_variants(),disabled_labeled_radio_variants()))),
"Checkbox" => padded_container_box(v_stack((
checkboxes_variants(),
Expand Down
34 changes: 34 additions & 0 deletions examples/widget-gallery/src/progresses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use floem::{view::View, views::v_stack};
use oxytail_base::widgets::{
common_props::OxyVariant,
progress::{progress, ProgressProps},
};

pub fn progresses_variants() -> impl View {
v_stack((
progress(
20,
80,
Some(ProgressProps {
variant: OxyVariant::Primary,
..Default::default()
}),
),
progress(
40,
80,
Some(ProgressProps {
variant: OxyVariant::Primary,
..Default::default()
}),
),
progress(
60,
80,
Some(ProgressProps {
variant: OxyVariant::Primary,
..Default::default()
}),
),
))
}
21 changes: 18 additions & 3 deletions oxytail-base/src/themes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use floem::{peniko::Color, style::Style};

use crate::widgets::{
badge::BadgeProps, button::ButtonProps, checkbox::CheckboxProps, common_props::OxyVariant,
radio_button::RadioProps, text_header::HeaderProps, text_input::InputProps,
toggle::ToggleProps, tooltip::TooltipProps,
progress::ProgressProps, radio_button::RadioProps, text_header::HeaderProps,
text_input::InputProps, toggle::ToggleProps, tooltip::TooltipProps,
};

// TODO: LOAD TTF FROM FILE SO THAT ITS CONSISTENT.
Expand Down Expand Up @@ -59,7 +59,9 @@ pub trait ThemeStyling {
/// Defines how a `toggle` should look like.
fn get_toggle_style(&self, toggle_props: ToggleProps) -> Box<dyn Fn(Style) -> Style + '_>;
/// Defines how a `radio_button` should look like.
/// Returns a tuple, where first argument styles the "dot" of the active radio and the second one is the "outer circle", containing the default state of the radio.
/// Returns a tuple, where
/// First element styles the "dot" of the active radio
/// Second element is the "outer circle", containing the default state of the radio.
fn get_radio_style(
&self,
radio_props: RadioProps,
Expand All @@ -79,4 +81,17 @@ pub trait ThemeStyling {

/// Defines how a `badge` should look like.
fn get_badge_style(&self, badge_props: BadgeProps) -> Box<dyn Fn(Style) -> Style + '_>;

/// Defines how a `progress` should look like.
/// First argument: inner progress
/// Second argument: outline
/// Third argument: the "ball at the end of the first arg"
fn get_progress_style(
&self,
progress_props: ProgressProps,
) -> (
Box<dyn Fn(Style) -> Style + '_>,
Box<dyn Fn(Style) -> Style + '_>,
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 @@ -8,3 +8,4 @@ pub mod text_header;
pub mod text_divider;
pub mod tooltip;
pub mod badge;
pub mod progress;
48 changes: 48 additions & 0 deletions oxytail-base/src/widgets/progress.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use std::fmt::Display;

use floem::{
style::FlexDirection,
unit::{PxPct, PxPctAuto},
view::View,
views::{container, empty, h_stack, Decorators},
};

use crate::get_current_theme;

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

#[derive(Default, Clone, Copy)]
pub struct ProgressProps {
pub variant: OxyVariant,
pub size: OxySize,
}

/// The progress element. You unfortunately, you need to define the width yourself for this one to work.
/// `value` should be a pixel/percentage value.
/// `max_value` should be the max_value.
/// value should be less or equal to max_value.
pub fn progress(
value: impl Into<PxPctAuto> + Copy + 'static,
max_value: impl Into<PxPctAuto> + Copy + 'static,
props: Option<ProgressProps>,
) -> impl View {
let props = props.unwrap_or(ProgressProps::default());

let theme = get_current_theme();
let (inner_enhancer, outer_enhancer, ball_enhancer) = theme.get_progress_style(props);

let ball_widget = empty();
let ball_widget = ball_widget.style(move |s| ball_enhancer(s));
let inner_widget = container(ball_widget).style(move |s| {
s.width(value)
.max_width(value)
.flex()
.flex_direction(FlexDirection::RowReverse)
});
let inner_widget = inner_widget.style(move |s| inner_enhancer(s));
let outline_widget = container(inner_widget).style(move |s| s.width(max_value));

let styled_progress = outline_widget.style(move |s| outer_enhancer(s));

styled_progress
}
19 changes: 16 additions & 3 deletions oxytail-theme-dark/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use oxytail_base::{
themes::{DefaultThemeProps, ThemeStyling},
widgets::{
badge::BadgeProps, button::ButtonProps, checkbox::CheckboxProps, common_props::OxyVariant,
radio_button::RadioProps, text_header::HeaderProps, text_input::InputProps,
toggle::ToggleProps, tooltip::TooltipProps,
progress::ProgressProps, radio_button::RadioProps, text_header::HeaderProps,
text_input::InputProps, toggle::ToggleProps, tooltip::TooltipProps,
},
};
use oxytail_theme_defaults::DEFAULT_ACCENT;
Expand Down Expand Up @@ -122,8 +122,21 @@ impl ThemeStyling for Theme {
)
}

/// Defines how a `badge` should look like.
fn get_badge_style(&self, badge_props: BadgeProps) -> Box<dyn Fn(Style) -> Style + '_> {
oxytail_theme_defaults::ThemeDefault::get_badge_style(badge_props, self.theme_defaults())
}

fn get_progress_style(
&self,
progress_props: ProgressProps,
) -> (
Box<dyn Fn(Style) -> Style + '_>,
Box<dyn Fn(Style) -> Style + '_>,
Box<dyn Fn(Style) -> Style + '_>,
) {
oxytail_theme_defaults::ThemeDefault::get_progress_style(
progress_props,
self.theme_defaults(),
)
}
}
75 changes: 75 additions & 0 deletions oxytail-theme-defaults/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use oxytail_base::{
button::ButtonProps,
checkbox::CheckboxProps,
common_props::{OxySize, OxyVariant},
progress::ProgressProps,
radio_button::RadioProps,
text_header::HeaderProps,
text_input::InputProps,
Expand Down Expand Up @@ -427,4 +428,78 @@ impl ThemeDefault {

Box::new(styles_creator)
}

/// Defines how a `progress` should look like. Returns a tuple
/// First argument: inner progress
/// Second argument: outline
/// Third argument: the "ball at the end of the first arg"
pub fn get_progress_style(
progress_props: ProgressProps,
theme_defaults: DefaultThemeProps,
) -> (
Box<dyn Fn(Style) -> Style>,
Box<dyn Fn(Style) -> Style>,
Box<dyn Fn(Style) -> Style>,
) {
let size = 26.0;
let curr_variant_color = (theme_defaults.get_variant_colors)(progress_props.variant);
let outer_styles_creator = move |s: Style| {
let base_style = s
.border(0.5)
.border_radius(16)
.border_color(Color::WHITE)
.background(Color::TRANSPARENT);
let variant_enhancer = |s: Style| match progress_props.variant {
OxyVariant::Default => {
s.border_color((theme_defaults.get_variant_colors)(OxyVariant::Neutral))
}
OxyVariant::Neutral => s.border_color(curr_variant_color),
_ => s.border_color(curr_variant_color),
};

let enhanced_style = variant_enhancer(base_style);

enhanced_style
};
let inner_styles_creator = move |s: Style| {
let base_style = s.background(Color::WHITE).border_radius(16).min_width(size);
let variant_enhancer = |s: Style| match progress_props.variant {
OxyVariant::Default => {
s.background((theme_defaults.get_variant_colors)(OxyVariant::Neutral))
}
OxyVariant::Neutral => s.background(curr_variant_color),
_ => s.background(curr_variant_color),
};

let enhanced_style = variant_enhancer(base_style);

enhanced_style
};
let ball_styles_creator = move |s: Style| {
let base_style = s
.min_width(size)
.min_height(size)
.border(3)
.border_radius(Pct(50.))
.background(Color::rgb8(29, 35, 42));

let variant_enhancer = |s: Style| match progress_props.variant {
OxyVariant::Default => {
s.border_color((theme_defaults.get_variant_colors)(OxyVariant::Neutral))
}
OxyVariant::Neutral => s.border_color(curr_variant_color),
_ => s.border_color(curr_variant_color),
};

let enhanced_style = variant_enhancer(base_style);

enhanced_style
};

(
Box::new(inner_styles_creator),
Box::new(outer_styles_creator),
Box::new(ball_styles_creator),
)
}
}
Loading