Skip to content

Commit

Permalink
refactor(widgets): 💡 use Variant to enable support for customizing …
Browse files Browse the repository at this point in the history
…the size of the FAB button
  • Loading branch information
M-Adoo authored and wjian23 committed Jan 15, 2025
1 parent 8569cdc commit 9b9a9ed
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 155 deletions.
144 changes: 71 additions & 73 deletions themes/material/src/classes/buttons_cls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ pub(super) fn init(classes: &mut Classes) {
filled_button_init(classes);
text_button_init(classes);
fab_init(classes);
mini_fab_init(classes);
large_fab_init(classes);
}

named_style_class!(common_btn => {
Expand Down Expand Up @@ -72,7 +70,7 @@ fn filled_button_init(classes: &mut Classes) {
}

fn button_init(classes: &mut Classes) {
fn outlined_interactive(w: Widget) -> Widget {
fn btn_interactive(w: Widget) -> Widget {
let outline = Palette::of(BuildCtx::get()).outline();
let w = FatObj::new(w)
.border(Border::all(BorderSide { color: outline.into(), width: 1. }))
Expand All @@ -85,103 +83,103 @@ fn button_init(classes: &mut Classes) {
.into_widget()
}

classes.insert(BUTTON, multi_class![common_btn, outlined_interactive]);
classes.insert(BUTTON, multi_class![common_btn, btn_interactive]);
classes.insert(BTN_LABEL, common_btn_label);
classes.insert(BTN_LEADING_ICON, empty_cls);
classes.insert(BTN_TRAILING_ICON, empty_cls);

classes.insert(BTN_LABEL_ONLY, multi_class![common_label_only, outlined_interactive]);
classes.insert(BTN_ICON_ONLY, multi_class![common_icon_only, outlined_interactive]);
}

fn fab_common_interactive(w: Widget, radius: Radius, btn_clamp: BoxClamp) -> Widget {
let color = BuildCtx::color();

let w = FatObj::new(w)
.background(
color
.clone()
.into_container_color(BuildCtx::get()),
)
.clamp(btn_clamp)
.border_radius(radius);
FatObj::new(base_interactive(w.into_widget(), radius))
.foreground(color.on_this_container_color(BuildCtx::get()))
.into_widget()
classes.insert(BTN_LABEL_ONLY, multi_class![common_label_only, btn_interactive]);
classes.insert(BTN_ICON_ONLY, multi_class![common_icon_only, btn_interactive]);
}

fn fab_init(classes: &mut Classes) {
const MINI_BTN_HEIGHT: f32 = 40.;
const BTN_HEIGHT: f32 = 56.;
fn fab_interactive(w: Widget) -> Widget {
let clamp = BoxClamp::min_width(BTN_HEIGHT).with_fixed_height(BTN_HEIGHT);
fab_common_interactive(w, md::RADIUS_16, clamp)
}

classes.insert(FAB_ICON_ONLY, multi_class![common_icon_only, fab_interactive]);
classes.insert(FAB_LABEL_ONLY, multi_class![
style_class! { padding: md::EDGES_HOR_24, text_style: btn_label_style(BTN_HEIGHT) },
fab_interactive
]);

classes.insert(FAB, multi_class![
style_class! {
padding: md::EDGES_HOR_16,
text_style: btn_label_style(24.)
},
fab_interactive
]);
classes.insert(FAB_LEADING_ICON, empty_cls);
classes.insert(FAB_TRAILING_ICON, empty_cls);
classes.insert(FAB_LABEL, common_btn_label);
}
const LARGE_BTN_HEIGHT: f32 = 96.;
const LARGE_ICON_SIZE: f32 = 36.;

fn mini_fab_init(classes: &mut Classes) {
fn fab_interactive(w: Widget) -> Widget { fab_common_interactive(w, md::RADIUS_12, BTN_40_CLAMP) }

classes.insert(MINI_FAB_ICON_ONLY, multi_class![common_icon_only, fab_interactive]);
classes.insert(MINI_FAB_LABEL_ONLY, multi_class![common_label_only, fab_interactive]);
classes.insert(MINI_FAB, multi_class![common_btn, fab_interactive]);
classes.insert(MINI_FAB_LEADING_ICON, empty_cls);
classes.insert(MINI_FAB_TRAILING_ICON, empty_cls);
classes.insert(MINI_FAB_LABEL, common_btn_label);
}

fn large_fab_init(classes: &mut Classes) {
const ICON_SIZE: f32 = 36.;
const BTN_HEIGHT: f32 = 96.;
fn fab_size() -> FabSize {
Provider::of::<FabSize>(BuildCtx::get()).map_or(FabSize::Normal, |f| *f)
}

fn label_style(line_height: f32) -> TextStyle {
fn large_label_style(line_height: f32) -> TextStyle {
let text_theme = TypographyTheme::of(BuildCtx::get());
let mut text_style = text_theme.title_large.text.clone();
text_style.line_height = line_height;
text_style
}

fn fab_interactive(w: Widget) -> Widget {
let clamp = BoxClamp::min_width(BTN_HEIGHT).with_fixed_height(BTN_HEIGHT);
fab_common_interactive(w, Radius::all(28.), clamp)
let color = BuildCtx::color();
let ctx = BuildCtx::get();
let background = color.clone().into_container_color(ctx);
let foreground = color.on_this_container_color(ctx);
let fab_size = fab_size();

let btn_height = match fab_size {
FabSize::Mini => MINI_BTN_HEIGHT,
FabSize::Normal => BTN_HEIGHT,
FabSize::Large => LARGE_BTN_HEIGHT,
};
let radius = match fab_size {
FabSize::Mini => md::RADIUS_12,
FabSize::Normal => md::RADIUS_16,
FabSize::Large => Radius::all(28.),
};

let w = FatObj::new(w)
.background(background)
.clamp(BoxClamp::min_width(btn_height).with_fixed_height(btn_height))
.border_radius(radius);

FatObj::new(base_interactive(w.into_widget(), radius))
.foreground(foreground)
.into_widget()
}

classes.insert(LARGE_FAB_ICON_ONLY, multi_class![
style_class! { text_line_height: ICON_SIZE },
classes.insert(FAB_ICON_ONLY, multi_class![
match fab_size() {
FabSize::Large => style_class! { text_line_height: LARGE_ICON_SIZE },
_ => common_icon_only,
},
fab_interactive
]);
classes.insert(LARGE_FAB_LABEL_ONLY, multi_class![
style_class! {
text_style: label_style(BTN_HEIGHT),
padding: md::EDGES_HOR_48,

classes.insert(FAB_LABEL_ONLY, multi_class![
match fab_size() {
FabSize::Mini => common_label_only,
FabSize::Normal =>
style_class! { padding: md::EDGES_HOR_24, text_style: btn_label_style(BTN_HEIGHT) },
FabSize::Large => style_class! {
text_style: large_label_style(LARGE_BTN_HEIGHT),
padding: md::EDGES_HOR_48,
},
},
fab_interactive
]);
classes.insert(LARGE_FAB, multi_class![
style_class! { padding: md::EDGES_HOR_32,
text_style: label_style(ICON_SIZE)

classes.insert(FAB, multi_class![
match fab_size() {
FabSize::Mini => common_btn,
FabSize::Normal => style_class! {
padding: md::EDGES_HOR_16,
text_style: btn_label_style(24.)
},
FabSize::Large => style_class! {
padding: md::EDGES_HOR_32,
text_style: large_label_style(LARGE_ICON_SIZE)
},
},
fab_interactive
]);
classes.insert(LARGE_FAB_LEADING_ICON, empty_cls);
classes.insert(LARGE_FAB_TRAILING_ICON, empty_cls);
classes.insert(LARGE_FAB_LABEL, style_class! { padding: md::EDGES_HOR_16 });
classes.insert(FAB_LEADING_ICON, empty_cls);
classes.insert(FAB_TRAILING_ICON, empty_cls);
classes.insert(FAB_LABEL, |w| match fab_size() {
FabSize::Large => FatObj::new(w)
.padding(md::EDGES_HOR_16)
.into_widget(),
_ => common_btn_label(w),
});
}

fn btn_label_style(line_height: f32) -> TextStyle {
Expand Down
Loading

0 comments on commit 9b9a9ed

Please sign in to comment.