ui/src/elements/icon.rs

356 lines
9.2 KiB
Rust
Raw Normal View History

2024-05-17 12:16:30 +00:00
use crate::{
2025-02-27 09:43:07 +00:00
builder::validator::iconinfo::IconInfo, gui_handler::gui::iconizable::IconizablePositioning,
2024-05-17 12:16:30 +00:00
prelude::*,
};
2023-01-16 09:53:52 +00:00
use anyhow::Result;
2024-08-29 10:37:22 +00:00
use assetpath::AssetPath;
2023-01-16 11:58:59 +00:00
use utilities::prelude::*;
use vulkan_rs::prelude::*;
2023-01-16 09:53:52 +00:00
use std::sync::{
Arc, RwLock,
2025-03-04 10:37:45 +00:00
atomic::{AtomicBool, Ordering::SeqCst},
2023-01-16 09:53:52 +00:00
};
2024-04-04 15:57:50 +00:00
use super::{
2025-03-04 10:37:45 +00:00
IconBuilderType,
2024-04-04 15:57:50 +00:00
fill_type::FillType,
wrapper::{IconizableWrapper, TextableWrapper},
};
2023-01-16 09:53:52 +00:00
pub struct IconBuilder {
content: Option<IconBuilderType>,
background: Option<FillTypeInfo>,
margin: u32,
text: Option<String>,
text_color: Color,
text_ratio: f32,
}
impl IconBuilder {
pub fn set_margin(mut self, margin: u32) -> Self {
self.margin = margin;
self
}
pub fn set_content(mut self, content: impl Into<IconBuilderType>) -> Self {
self.content = Some(content.into());
self
}
pub fn set_background(mut self, background: FillTypeInfo) -> Self {
self.background = Some(background);
self
}
pub fn set_text(mut self, text: &str) -> Self {
self.text = Some(text.to_string());
self
}
pub fn set_text_color(mut self, color: Color) -> Self {
self.text_color = color;
self
}
pub fn set_text_ratio(mut self, ratio: f32) -> Self {
self.text_ratio = ratio;
self
}
2025-03-04 11:25:02 +00:00
pub fn build(self, gui_handler: &mut GuiHandler) -> Result<Arc<Icon>> {
2025-03-04 10:37:45 +00:00
let framable = Framable::new(gui_handler.width(), gui_handler.height(), false)?;
2023-01-16 09:53:52 +00:00
2025-03-04 10:37:45 +00:00
let iconizable_wrapper = IconizableWrapper::new(
gui_handler,
framable.clone(),
self.content,
None,
self.margin,
)?;
2023-01-16 09:53:52 +00:00
let background = RwLock::new(
self.background
2025-03-04 10:37:45 +00:00
.map(|info| FillType::new(gui_handler, framable.clone(), info))
2023-01-16 09:53:52 +00:00
.transpose()?,
);
let textable_wrapper = TextableWrapper::new(
framable.clone(),
self.text_color,
self.text_ratio,
TextAlignment::Center,
);
if let Some(text) = self.text {
2025-03-04 10:37:45 +00:00
textable_wrapper.set_text(gui_handler, &text, false)?;
2023-01-16 09:53:52 +00:00
}
2024-05-17 12:16:30 +00:00
let info_icon = IconizableWrapper::new(
2025-03-04 10:37:45 +00:00
gui_handler,
2024-05-17 12:16:30 +00:00
framable.clone(),
None,
Some(IconizablePositioning {
left: 1.2,
right: 0.0,
top: 1.2,
bottom: 0.0,
}),
0,
)?;
2023-01-16 09:53:52 +00:00
Ok(Arc::new(Icon {
framable,
background,
iconizable_wrapper,
textable_wrapper,
2024-05-17 12:16:30 +00:00
info_icon,
2023-01-16 09:53:52 +00:00
visible: AtomicBool::new(false),
}))
}
}
pub struct Icon {
framable: Arc<Framable>,
background: RwLock<Option<FillType>>,
iconizable_wrapper: IconizableWrapper,
textable_wrapper: TextableWrapper,
2024-05-17 12:16:30 +00:00
info_icon: IconizableWrapper,
2023-01-16 09:53:52 +00:00
visible: AtomicBool,
}
impl Icon {
pub fn builder() -> IconBuilder {
IconBuilder {
content: None,
background: None,
margin: 0,
text: None,
text_color: Color::Black,
text_ratio: 0.7,
}
}
2025-03-04 11:25:02 +00:00
pub fn clear_icon(&self, gui_handler: &mut GuiHandler) -> Result<()> {
2025-03-04 10:37:45 +00:00
self.iconizable_wrapper
.clear_icon(gui_handler, self.visible())
2023-01-16 09:53:52 +00:00
}
2025-03-04 11:25:02 +00:00
pub fn set_icon(&self, gui_handler: &mut GuiHandler, icon: &Arc<Image>) -> Result<()> {
2025-03-04 10:37:45 +00:00
self.iconizable_wrapper
.set_icon(gui_handler, icon, self.visible())
2023-01-16 09:53:52 +00:00
}
2025-03-04 10:37:45 +00:00
pub fn set_icon_from_path(
&self,
2025-03-04 11:25:02 +00:00
gui_handler: &mut GuiHandler,
2025-03-04 10:37:45 +00:00
asset_path: AssetPath,
) -> Result<()> {
self.iconizable_wrapper
.set_icon(gui_handler, asset_path, self.visible())
2024-08-29 10:37:22 +00:00
}
2025-03-04 11:25:02 +00:00
pub fn set_margin(&self, gui_handler: &mut GuiHandler, margin: u32) -> Result<()> {
2025-03-04 10:37:45 +00:00
self.iconizable_wrapper.set_margin(gui_handler, margin)
2023-01-16 09:53:52 +00:00
}
2025-03-04 10:37:45 +00:00
pub fn set_background(
&self,
2025-03-04 11:25:02 +00:00
gui_handler: &mut GuiHandler,
2025-03-04 10:37:45 +00:00
background: impl Into<FillTypeInfo>,
) -> Result<()> {
super::set_background(
gui_handler,
self.visible(),
&self.framable,
&self.background,
background,
)
2023-01-16 09:53:52 +00:00
}
pub fn clear_background(&self) {
*self.background.write().unwrap() = None;
}
2025-03-04 11:25:02 +00:00
pub fn set_text(&self, gui_handler: &mut GuiHandler, text: impl ToString) -> Result<()> {
2025-03-04 10:37:45 +00:00
self.textable_wrapper
.set_text(gui_handler, text, self.visible())
2023-01-16 09:53:52 +00:00
}
2025-03-04 11:25:02 +00:00
pub fn clear_text(&self, gui_handler: &mut GuiHandler) -> Result<()> {
2025-03-04 10:37:45 +00:00
self.textable_wrapper
.set_text(gui_handler, "", self.visible())
2023-01-16 09:53:52 +00:00
}
2025-03-04 11:25:02 +00:00
pub fn set_text_color(&self, gui_handler: &mut GuiHandler, color: Color) -> Result<()> {
2025-03-04 10:37:45 +00:00
self.textable_wrapper.set_text_color(gui_handler, color)
2023-01-16 09:53:52 +00:00
}
2025-03-04 11:25:02 +00:00
pub fn set_info_icon(&self, gui_handler: &mut GuiHandler, button: &Arc<Image>) -> Result<()> {
2025-03-04 10:37:45 +00:00
self.info_icon.set_icon(gui_handler, button, self.visible())
2024-05-17 12:16:30 +00:00
}
2025-03-04 11:25:02 +00:00
pub fn clear_info_icon(&self, gui_handler: &mut GuiHandler) -> Result<()> {
2025-03-04 10:37:45 +00:00
self.info_icon.clear_icon(gui_handler, self.visible())
2024-05-17 12:16:30 +00:00
}
2025-03-04 11:25:02 +00:00
pub fn try_from(icon_info: &IconInfo, gui_handler: &mut GuiHandler) -> Result<Arc<Self>> {
2023-01-16 09:53:52 +00:00
let mut icon_builder = Icon::builder().set_text_color(icon_info.text_color);
if let Some(text_ratio) = icon_info.text_ratio {
icon_builder = icon_builder.set_text_ratio(text_ratio);
}
if let Some(margin) = icon_info.margin {
icon_builder = icon_builder.set_margin(margin);
}
if let Some(icon) = &icon_info.icon {
icon_builder = icon_builder.set_content(icon.clone());
}
if let Some(fill_type_info) = icon_info.background_type.clone() {
icon_builder = icon_builder.set_background(fill_type_info);
}
{
let t = icon_info.text.read().unwrap();
let text = t.as_str();
if !text.is_empty() {
icon_builder = icon_builder.set_text(text);
}
}
2025-03-04 10:37:45 +00:00
icon_builder.build(gui_handler)
2023-01-16 09:53:52 +00:00
}
pub fn icon(&self) -> Result<Option<Arc<Image>>> {
self.iconizable_wrapper.icon()
}
2023-01-18 08:45:16 +00:00
pub fn extent(&self) -> (i32, i32) {
(
self.framable.right() - self.framable.left(),
self.framable.bottom() - self.framable.top(),
)
}
2025-03-04 11:25:02 +00:00
fn disable_base(&self, gui_handler: &mut GuiHandler) -> Result<()> {
2025-03-04 10:37:45 +00:00
self.framable.delete(gui_handler)?;
2023-01-16 09:53:52 +00:00
2025-03-04 10:37:45 +00:00
self.iconizable_wrapper.disable(gui_handler)?;
self.textable_wrapper.disable(gui_handler)?;
self.info_icon.disable(gui_handler)?;
2023-01-16 09:53:52 +00:00
if let Some(background) = self.background.read().unwrap().as_ref() {
2025-03-04 10:37:45 +00:00
background.disable(gui_handler)?;
2023-01-16 09:53:52 +00:00
}
Ok(())
}
}
2025-03-04 11:25:02 +00:00
impl GuiElementTraits for Icon {
fn gridable(&self) -> Option<&dyn Gridable> {
2023-01-16 09:53:52 +00:00
Some(self)
}
fn visibility(&self) -> Option<&dyn Visibility> {
Some(self)
}
2025-03-04 11:25:02 +00:00
fn downcast<'a>(&'a self) -> Option<GuiElement<'a>> {
2023-01-16 09:53:52 +00:00
Some(GuiElement::Icon(self))
}
}
impl Visibility for Icon {
fn visible(&self) -> bool {
self.visible.load(SeqCst)
}
2025-03-04 11:25:02 +00:00
fn set_visibility(&self, gui_handler: &mut GuiHandler, visibility: bool) -> Result<()> {
2023-01-16 09:53:52 +00:00
if visibility != self.visible.load(SeqCst) {
self.visible.store(visibility, SeqCst);
if visibility {
2025-03-04 10:37:45 +00:00
self.framable.add(gui_handler)?;
2023-01-16 09:53:52 +00:00
2025-03-04 10:37:45 +00:00
self.info_icon.enable(gui_handler)?;
self.iconizable_wrapper.enable(gui_handler)?;
self.textable_wrapper.enable(gui_handler)?;
2023-01-16 09:53:52 +00:00
if let Some(background) = self.background.read().unwrap().as_ref() {
2025-03-04 10:37:45 +00:00
background.enable(gui_handler)?;
2023-01-16 09:53:52 +00:00
}
} else {
2025-03-04 10:37:45 +00:00
self.disable_base(gui_handler)?;
2023-01-16 09:53:52 +00:00
}
}
Ok(())
}
}
2025-03-04 11:25:02 +00:00
impl Gridable for Icon {
2023-01-16 09:53:52 +00:00
fn set_frame(
&self,
2025-03-04 11:25:02 +00:00
gui_handler: &mut GuiHandler,
2023-01-16 09:53:52 +00:00
x: i32,
y: i32,
w: u32,
h: u32,
vert_align: VerticalAlign,
hori_align: HorizontalAlign,
) -> Result<()> {
2025-03-04 10:37:45 +00:00
self.framable
.set_frame(gui_handler, x, y, w, h, vert_align, hori_align);
2023-01-16 09:53:52 +00:00
2025-03-04 10:37:45 +00:00
self.iconizable_wrapper.update_frame(gui_handler)?;
self.textable_wrapper.update(gui_handler)?;
self.info_icon.update_frame(gui_handler)?;
2023-01-16 09:53:52 +00:00
if let Some(background) = self.background.read().unwrap().as_ref() {
2025-03-04 10:37:45 +00:00
background.update_frame(gui_handler)?;
2023-01-16 09:53:52 +00:00
}
Ok(())
}
2025-03-04 11:25:02 +00:00
fn selectable(&self) -> Option<&Arc<Selectable>> {
2023-01-16 09:53:52 +00:00
None
}
fn type_name(&self) -> &str {
"Icon"
}
fn set_layer(&self, layer: i32) -> Result<()> {
self.framable.set_ui_layer(layer);
self.iconizable_wrapper.set_ui_layer(layer)?;
self.textable_wrapper.set_ui_layer(layer)?;
2024-05-17 12:29:22 +00:00
self.info_icon.set_ui_layer(layer)?;
2023-01-16 09:53:52 +00:00
if let Some(background) = self.background.read().unwrap().as_ref() {
background.set_ui_layer(layer);
}
Ok(())
}
2024-04-21 05:41:08 +00:00
fn position_extent(&self) -> (i32, i32, u32, u32) {
self.framable.position()
}
2023-01-16 09:53:52 +00:00
}