ui/src/elements/label.rs

287 lines
6.9 KiB
Rust
Raw Normal View History

2024-04-26 06:28:05 +00:00
use crate::{
builder::validator::labelinfo::LabelInfo, guihandler::gui::iconizable::IconizablePositioning,
prelude::*,
};
use super::{
fill_type::FillType,
wrapper::{IconizableWrapper, TextableWrapper},
};
2023-01-16 09:53:52 +00:00
2024-04-26 06:28:05 +00:00
use vulkan_rs::prelude::*;
2023-01-16 09:53:52 +00:00
use std::sync::{
atomic::{AtomicBool, Ordering::SeqCst},
Arc, RwLock,
};
use anyhow::Result;
pub struct LabelBuilder {
text_alignment: TextAlignment,
text_ratio: f32,
text_color: Color,
text: Option<String>,
background: Option<FillTypeInfo>,
}
impl LabelBuilder {
pub fn set_text(mut self, text: impl Into<String>) -> Self {
self.text = Some(text.into());
self
}
pub fn set_ratio(mut self, ratio: f32) -> Self {
self.text_ratio = ratio;
self
}
pub fn set_text_color(mut self, text_color: impl Into<Color>) -> Self {
self.text_color = text_color.into();
self
}
pub fn set_text_alignment(mut self, text_alignment: TextAlignment) -> Self {
self.text_alignment = text_alignment;
self
}
pub fn set_background(mut self, background: impl Into<FillTypeInfo>) -> Self {
self.background = Some(background.into());
self
}
pub fn build(self, gui_handler: Arc<GuiHandler>) -> Result<Arc<Label>> {
let framable = Framable::new(gui_handler, false)?;
let textable_wrapper = TextableWrapper::new(
framable.clone(),
self.text_color,
self.text_ratio,
self.text_alignment,
);
if let Some(text) = &self.text {
textable_wrapper.set_text(text, false)?;
}
let background = self
.background
.map(|info| FillType::new(framable.clone(), info))
.transpose()?;
2024-04-26 06:28:05 +00:00
let info_icon = IconizableWrapper::new(
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(Label {
framable,
background: RwLock::new(background),
textable_wrapper,
2024-04-26 06:28:05 +00:00
info_icon,
2023-01-16 09:53:52 +00:00
visible: AtomicBool::new(false),
}))
}
}
pub struct Label {
pub(crate) framable: Arc<Framable>,
background: RwLock<Option<FillType>>,
textable_wrapper: TextableWrapper,
2024-04-26 06:28:05 +00:00
info_icon: IconizableWrapper,
2023-01-16 09:53:52 +00:00
visible: AtomicBool,
}
impl Label {
pub fn builder() -> LabelBuilder {
LabelBuilder {
text_alignment: TextAlignment::Center,
text_ratio: 0.7,
text_color: Color::Black,
text: None,
background: None,
}
}
pub fn set_text(&self, text: impl ToString) -> Result<()> {
self.textable_wrapper.set_text(text, self.visible())
}
pub fn text(&self) -> Result<Option<String>> {
self.textable_wrapper.text()
}
pub fn set_text_color(&self, text_color: Color) -> Result<()> {
self.textable_wrapper.set_text_color(text_color)
}
pub fn set_alignment(&self, alignment: TextAlignment) -> Result<()> {
self.textable_wrapper.set_alignment(alignment)
}
pub fn set_text_ratio(&self, ratio: f32) -> Result<()> {
self.textable_wrapper.set_height_ratio(ratio)
}
pub fn text_ratio(&self) -> f32 {
self.textable_wrapper.height_ratio()
}
2024-04-26 06:28:05 +00:00
pub fn set_info_icon(&self, button: &Arc<Image>) -> Result<()> {
self.info_icon.set_icon(button, self.visible())
}
pub fn clear_info_icon(&self) -> Result<()> {
self.info_icon.clear_icon(self.visible())
}
2023-01-16 09:53:52 +00:00
pub fn set_background(&self, background: impl Into<FillTypeInfo>) -> Result<()> {
2023-01-19 12:05:48 +00:00
super::set_background(self.visible(), &self.framable, &self.background, background)
2023-01-16 09:53:52 +00:00
}
pub fn try_from(label_info: &LabelInfo, gui_handler: &Arc<GuiHandler>) -> Result<Arc<Self>> {
let text = label_info.text.read().unwrap().clone();
let color = label_info.text_color;
let mut label_builder = Label::builder()
.set_text_color(color)
.set_text_alignment(label_info.text_alignment);
if let Some(background_type) = &label_info.background_type {
label_builder = label_builder.set_background(background_type.clone());
}
if let Some(ratio) = label_info.text_ratio {
label_builder = label_builder.set_ratio(ratio);
}
if !text.is_empty() {
label_builder = label_builder.set_text(text);
}
label_builder.build(gui_handler.clone())
}
fn disable_base(&self) -> Result<()> {
self.framable.delete()?;
self.textable_wrapper.disable()?;
if let Some(background) = self.background.read().unwrap().as_ref() {
background.disable()?;
}
Ok(())
}
}
impl GuiElementTraits for Label {
fn gridable(&self) -> Option<&dyn Gridable> {
Some(self)
}
fn visibility(&self) -> Option<&dyn Visibility> {
Some(self)
}
fn downcast<'a>(&'a self) -> Option<GuiElement<'a>> {
Some(GuiElement::Label(self))
}
}
impl Visibility for Label {
fn visible(&self) -> bool {
self.visible.load(SeqCst)
}
fn set_visibility(&self, visibility: bool) -> Result<()> {
if visibility != self.visible() {
self.visible.store(visibility, SeqCst);
if visibility {
self.framable.add()?;
self.textable_wrapper.enable()?;
if let Some(background) = self.background.read().unwrap().as_ref() {
background.enable()?;
}
} else {
self.disable_base()?;
}
}
Ok(())
}
}
impl Gridable for Label {
fn set_frame(
&self,
x: i32,
y: i32,
w: u32,
h: u32,
vert_align: VerticalAlign,
hori_align: HorizontalAlign,
) -> Result<()> {
self.framable.set_frame(x, y, w, h, vert_align, hori_align);
self.textable_wrapper.update()?;
if let Some(background) = self.background.read().unwrap().as_ref() {
background.update_frame()?;
}
Ok(())
}
fn selectable(&self) -> Option<&Arc<Selectable>> {
None
}
fn type_name(&self) -> &str {
"Label"
}
fn set_layer(&self, layer: i32) -> Result<()> {
self.framable.set_ui_layer(layer);
self.textable_wrapper.set_ui_layer(layer)?;
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
}
impl Drop for Label {
fn drop(&mut self) {
if self.visible.load(SeqCst) {
self.disable_base().unwrap();
}
}
}