OneLauncher-Cracked/packages/oneclient_app/src/view/app/clusters/instance/shell.rs

209 lines
7 KiB
Rust

use freya::prelude::*;
use crate::components::{Button, Icon, IconType, OverlayPopup, ScrollArea};
use crate::theme::colors;
use crate::ui::border_all_color;
pub const DIALOG_WIDTH: f32 = 1020.;
pub const DIALOG_HEIGHT: f32 = 660.;
pub const RAIL_WIDTH: f32 = 368.;
pub const PANE_PADDING: f32 = 24.;
pub struct Shell {
pub rail: Element,
pub eyebrow: Option<String>,
pub title: String,
pub subtitle: String,
pub body: Element,
pub scrolls_itself: bool,
pub note: String,
pub secondary_label: String,
pub primary_label: String,
pub primary_enabled: bool,
pub on_close: EventHandler<()>,
pub on_secondary: EventHandler<()>,
pub on_primary: EventHandler<()>,
}
pub fn shell(parts: Shell) -> Element {
let Shell {
rail,
eyebrow,
title,
subtitle,
body,
scrolls_itself,
note,
secondary_label,
primary_label,
primary_enabled,
on_close,
on_secondary,
on_primary,
} = parts;
let close_scrim = on_close.clone();
OverlayPopup::new()
.on_close(move |()| close_scrim.call(()))
.child(
rect()
.width(Size::window_percent(100.))
.height(Size::window_percent(100.))
.center()
.child(
rect()
.horizontal()
.width(Size::px(DIALOG_WIDTH))
.height(Size::px(DIALOG_HEIGHT))
.max_width(Size::window_percent(94.))
.max_height(Size::window_percent(92.))
.content(Content::Flex)
.corner_radius(CornerRadius::new_all(16.))
.overflow(Overflow::Clip)
.background(colors::page_elevated())
.border(border_all_color(1., colors::component_border()))
.child(rail)
.child(
rect()
.vertical()
.width(Size::flex(1.0))
.height(Size::fill())
.content(Content::Flex)
.child(header(eyebrow, title, subtitle, on_close))
.child(if scrolls_itself {
rect()
.width(Size::fill())
.height(Size::flex(1.0))
.padding(Gaps::new(0., PANE_PADDING, 8., PANE_PADDING))
.child(body)
.into_element()
} else {
ScrollArea::new()
.width(Size::fill())
.height(Size::flex(1.0))
.padding(Gaps::new(0., PANE_PADDING, 8., PANE_PADDING))
.scrollbar_gutter(true)
.child(body)
.into_element()
})
.child(footer(
note,
secondary_label,
primary_label,
primary_enabled,
on_secondary,
on_primary,
)),
),
),
)
.into_element()
}
fn header(eyebrow: Option<String>, title: String, subtitle: String, on_close: EventHandler<()>) -> Element {
rect()
.horizontal()
.width(Size::fill())
.content(Content::Flex)
.cross_align(Alignment::Start)
.spacing(16.)
.padding(Gaps::new(22., PANE_PADDING, 16., PANE_PADDING))
.child(
rect()
.vertical()
.width(Size::flex(1.0))
.spacing(5.)
.maybe_child(eyebrow.map(|eyebrow| {
label()
.text(eyebrow)
.font_size(11.)
.font_weight(FontWeight::MEDIUM)
.letter_spacing(1.6)
.color(colors::fg_secondary())
}))
.child(
label()
.text(title)
.font_size(20.)
.font_weight(FontWeight::SEMI_BOLD)
.color(colors::fg_primary()),
)
.child(
label()
.text(subtitle)
.font_size(13.)
.line_height(1.35)
.color(colors::fg_secondary()),
),
)
.child(
Button::new()
.ghost()
.icon()
.alt("Close")
.on_press(move |_| on_close.call(()))
.child(Icon::new(IconType::XClose).size(16.)),
)
.into_element()
}
fn footer(
note: String,
secondary_label: String,
primary_label: String,
primary_enabled: bool,
on_secondary: EventHandler<()>,
on_primary: EventHandler<()>,
) -> Element {
rect()
.horizontal()
.width(Size::fill())
.content(Content::Flex)
.cross_align(Alignment::Center)
.spacing(20.)
.padding(Gaps::new(16., PANE_PADDING, 16., PANE_PADDING))
.border(
Border::new()
.fill(colors::component_border())
.width(BorderWidth {
top: 1.,
right: 0.,
bottom: 0.,
left: 0.,
}),
)
.child(
label()
.text(note)
.width(Size::flex(1.0))
.font_size(12.)
.line_height(1.35)
.max_lines(2)
.color(colors::fg_secondary()),
)
.child(
rect()
.horizontal()
.spacing(10.)
.cross_align(Alignment::Center)
.child(
Button::new()
.ghost()
.on_press(move |_| on_secondary.call(()))
.text(secondary_label),
)
.child(
Button::new()
.primary()
.enabled(primary_enabled)
.on_press(move |_| {
if primary_enabled {
on_primary.call(());
}
})
.text(primary_label),
),
)
.into_element()
}