#![doc = include_str!("../README.md")]
#![forbid(unsafe_code)]
#[cfg(not(any(feature = "filled", feature = "outline")))]
compile_error!("At least one of `filled` or `outline` features must be enabled.");
#[cfg(feature = "compressed")]
use include_flate::flate;
use egui::epaint::text::{FontInsert, FontPriority, InsertFontFamily};
use egui::{Button, FontData, FontFamily, Frame, Response, RichText, Widget};
pub mod icons;
#[cfg(all(feature = "filled", not(feature = "compressed")))]
pub(crate) const FONT_DATA: &[u8] = include_bytes!("../MaterialSymbolsRounded_Filled-Regular.ttf");
#[cfg(all(
feature = "outline",
not(feature = "filled"),
not(feature = "compressed")
))]
pub(crate) const FONT_DATA: &[u8] = include_bytes!("../MaterialSymbolsRounded-Regular.ttf");
#[cfg(all(feature = "filled", feature = "outline", not(feature = "compressed")))]
pub(crate) const FONT_DATA_OUTLINED: &[u8] =
include_bytes!("../MaterialSymbolsRounded-Regular.ttf");
#[cfg(all(feature = "filled", feature = "compressed"))]
flate!(pub(crate) static FONT_DATA: [u8] from "MaterialSymbolsRounded_Filled-Regular.ttf");
#[cfg(all(feature = "outline", not(feature = "filled"), feature = "compressed"))]
flate!(pub(crate) static FONT_DATA: [u8] from "MaterialSymbolsRounded-Regular.ttf");
#[cfg(all(feature = "filled", feature = "outline", feature = "compressed"))]
flate!(pub(crate) static FONT_DATA_OUTLINED: [u8] from "MaterialSymbolsRounded-Regular.ttf");
pub const FONT_FAMILY: &str = "material-icons";
pub const FONT_FAMILY_OUTLINED: &str = "material-icons-outlined";
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum IconStyle {
Filled,
Outlined,
}
#[derive(Clone, Copy, Debug)]
pub struct MaterialIcon {
pub codepoint: &'static str,
pub style: IconStyle,
}
impl MaterialIcon {
pub const fn new(codepoint: &'static str) -> Self {
#[cfg(feature = "filled")]
{
Self {
codepoint,
style: IconStyle::Filled,
}
}
#[cfg(not(feature = "filled"))]
{
Self {
codepoint,
style: IconStyle::Outlined,
}
}
}
#[cfg(feature = "outline")]
pub const fn outlined(self) -> Self {
Self {
codepoint: self.codepoint,
style: IconStyle::Outlined,
}
}
#[cfg(feature = "filled")]
pub const fn filled(self) -> Self {
Self {
codepoint: self.codepoint,
style: IconStyle::Filled,
}
}
pub fn font_family(&self) -> FontFamily {
match self.style {
IconStyle::Filled => FontFamily::Name(FONT_FAMILY.into()),
IconStyle::Outlined => FontFamily::Name(FONT_FAMILY_OUTLINED.into()),
}
}
pub fn rich_text(self) -> RichText {
RichText::new(self.codepoint).family(self.font_family())
}
}
impl From<MaterialIcon> for RichText {
fn from(icon: MaterialIcon) -> Self {
icon.rich_text()
}
}
impl From<MaterialIcon> for egui::WidgetText {
fn from(icon: MaterialIcon) -> Self {
icon.rich_text().into()
}
}
impl From<MaterialIcon> for &str {
fn from(icon: MaterialIcon) -> Self {
icon.codepoint
}
}
impl From<MaterialIcon> for String {
fn from(icon: MaterialIcon) -> Self {
icon.codepoint.to_string()
}
}
pub fn font_insert() -> FontInsert {
let mut data = FontData::from_static(&FONT_DATA);
data.tweak.y_offset_factor = 0.05;
#[cfg(all(feature = "outline", not(feature = "filled")))]
let families = vec![
InsertFontFamily {
family: FontFamily::Proportional,
priority: FontPriority::Lowest,
},
InsertFontFamily {
family: FontFamily::Name(FONT_FAMILY.into()),
priority: FontPriority::Highest,
},
InsertFontFamily {
family: FontFamily::Name(FONT_FAMILY_OUTLINED.into()),
priority: FontPriority::Highest,
},
];
#[cfg(feature = "filled")]
let families = vec![
InsertFontFamily {
family: FontFamily::Proportional,
priority: FontPriority::Lowest,
},
InsertFontFamily {
family: FontFamily::Name(FONT_FAMILY.into()),
priority: FontPriority::Highest,
},
];
FontInsert::new(FONT_FAMILY, data, families)
}
#[cfg(all(feature = "filled", feature = "outline"))]
pub fn font_insert_outlined() -> FontInsert {
let mut data = FontData::from_static(&FONT_DATA_OUTLINED);
data.tweak.y_offset_factor = 0.05;
FontInsert::new(
FONT_FAMILY_OUTLINED,
data,
vec![
InsertFontFamily {
family: FontFamily::Proportional,
priority: FontPriority::Lowest,
},
InsertFontFamily {
family: FontFamily::Name(FONT_FAMILY_OUTLINED.into()),
priority: FontPriority::Highest,
},
],
)
}
pub fn initialize(ctx: &egui::Context) {
ctx.add_font(font_insert());
#[cfg(all(feature = "filled", feature = "outline"))]
ctx.add_font(font_insert_outlined());
}
pub fn icon_button(ui: &mut egui::Ui, icon: MaterialIcon) -> Response {
Frame::new()
.show(ui, |ui| {
Button::new(icon.rich_text().size(18.0)).frame(false).ui(ui)
})
.inner
}
pub fn icon_text(icon: MaterialIcon) -> RichText {
icon.rich_text()
}