2024-04-04 15:57:50 +00:00
|
|
|
use crate::{
|
2025-02-27 09:43:07 +00:00
|
|
|
gui_handler::gui::iconizable::{IconBuilderType, IconizablePositioning},
|
2024-04-04 15:57:50 +00:00
|
|
|
prelude::*,
|
|
|
|
};
|
|
|
|
use anyhow::Result;
|
|
|
|
use std::sync::{
|
|
|
|
atomic::{AtomicU32, Ordering::SeqCst},
|
|
|
|
Arc, Mutex,
|
|
|
|
};
|
|
|
|
use utilities::prelude::*;
|
|
|
|
use vulkan_rs::prelude::*;
|
|
|
|
|
|
|
|
pub(crate) struct TextableWrapper {
|
|
|
|
framable: Arc<Framable>,
|
|
|
|
|
|
|
|
textable: Mutex<Option<Arc<Textable>>>,
|
|
|
|
|
|
|
|
color: Mutex<Color>,
|
|
|
|
ratio: Mutex<f32>,
|
|
|
|
alignment: Mutex<TextAlignment>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TextableWrapper {
|
|
|
|
pub(crate) fn new(
|
|
|
|
framable: Arc<Framable>,
|
|
|
|
color: Color,
|
|
|
|
ratio: f32,
|
|
|
|
alignment: TextAlignment,
|
|
|
|
) -> Self {
|
|
|
|
TextableWrapper {
|
|
|
|
framable,
|
|
|
|
|
|
|
|
textable: Mutex::new(None),
|
|
|
|
|
|
|
|
color: Mutex::new(color),
|
|
|
|
ratio: Mutex::new(ratio),
|
|
|
|
alignment: Mutex::new(alignment),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn set_ui_layer(&self, layer: i32) -> Result<()> {
|
|
|
|
self.framable.set_ui_layer(layer);
|
|
|
|
|
|
|
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
|
|
|
textable.set_ui_layer(layer);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn set_text_color(&self, text_color: Color) -> Result<()> {
|
|
|
|
*self.color.lock().unwrap() = text_color;
|
|
|
|
|
|
|
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
|
|
|
textable.set_text_color(text_color)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn set_text(&self, text: impl ToString, is_visible: bool) -> Result<()> {
|
|
|
|
let text = text.to_string();
|
|
|
|
let mut textable = self.textable.lock().unwrap();
|
|
|
|
|
|
|
|
match textable.as_ref() {
|
|
|
|
Some(current_textable) => {
|
|
|
|
if text.is_empty() {
|
|
|
|
current_textable.clear_callback();
|
|
|
|
|
|
|
|
if is_visible {
|
|
|
|
current_textable.delete()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
*textable = None;
|
|
|
|
} else {
|
|
|
|
current_textable.set_text(text)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
if !text.is_empty() {
|
|
|
|
let new_textable = Textable::new(
|
|
|
|
self.framable.clone(),
|
|
|
|
text,
|
|
|
|
*self.ratio.lock().unwrap(),
|
|
|
|
*self.alignment.lock().unwrap(),
|
|
|
|
*self.color.lock().unwrap(),
|
|
|
|
)?;
|
|
|
|
|
|
|
|
if self.framable.is_framed() {
|
|
|
|
new_textable.update_text()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
new_textable.set_ui_layer(self.framable.ui_layer());
|
|
|
|
|
|
|
|
if is_visible {
|
|
|
|
new_textable.add()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
*textable = Some(new_textable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn text(&self) -> Result<Option<String>> {
|
|
|
|
Ok(self
|
|
|
|
.textable
|
|
|
|
.lock()
|
|
|
|
.unwrap()
|
|
|
|
.as_ref()
|
|
|
|
.map(|textable| textable.text()))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn set_height_ratio(&self, height_ratio: f32) -> Result<()> {
|
|
|
|
*self.ratio.lock().unwrap() = height_ratio;
|
|
|
|
|
|
|
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
|
|
|
textable.set_size(height_ratio)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn height_ratio(&self) -> f32 {
|
|
|
|
*self.ratio.lock().unwrap()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn set_alignment(&self, alignment: TextAlignment) -> Result<()> {
|
|
|
|
*self.alignment.lock().unwrap() = alignment;
|
|
|
|
|
|
|
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
|
|
|
textable.set_text_alignment(alignment)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn update(&self) -> Result<()> {
|
|
|
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
|
|
|
textable.update_text()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn enable(&self) -> Result<()> {
|
|
|
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
|
|
|
textable.add()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn disable(&self) -> Result<()> {
|
|
|
|
if let Some(textable) = self.textable.lock().unwrap().as_ref() {
|
|
|
|
textable.delete()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for TextableWrapper {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
if let Some(current_textable) = self.textable.lock().unwrap().as_ref() {
|
|
|
|
current_textable.clear_callback();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) struct IconizableWrapper {
|
|
|
|
framable: Arc<Framable>,
|
|
|
|
|
|
|
|
iconizable: Mutex<Option<Arc<Iconizable>>>,
|
|
|
|
positioning: Option<IconizablePositioning>,
|
|
|
|
margin: AtomicU32,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IconizableWrapper {
|
|
|
|
pub(crate) fn new(
|
|
|
|
framable: Arc<Framable>,
|
|
|
|
builder: Option<IconBuilderType>,
|
|
|
|
positioning: Option<IconizablePositioning>,
|
|
|
|
margin: u32,
|
|
|
|
) -> Result<Self> {
|
|
|
|
let iconizable: Option<Result<Arc<Iconizable>>> = builder.map(|content| {
|
|
|
|
let iconizable = Iconizable::new(framable.clone(), content, positioning.clone())?;
|
|
|
|
|
|
|
|
iconizable.set_margin(margin)?;
|
|
|
|
|
|
|
|
Ok(iconizable)
|
|
|
|
});
|
|
|
|
|
|
|
|
let iconizable = iconizable.transpose()?;
|
|
|
|
|
|
|
|
Ok(Self {
|
|
|
|
framable,
|
|
|
|
|
|
|
|
iconizable: Mutex::new(iconizable),
|
|
|
|
positioning,
|
|
|
|
margin: AtomicU32::new(margin),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn set_ui_layer(&self, layer: i32) -> Result<()> {
|
|
|
|
self.framable.set_ui_layer(layer);
|
|
|
|
|
|
|
|
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
|
|
|
iconizable.set_ui_layer(layer);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn clear_icon(&self, is_visible: bool) -> Result<()> {
|
|
|
|
let mut iconizable = self.iconizable.lock().unwrap();
|
|
|
|
|
|
|
|
if let Some(iconizable) = iconizable.as_ref() {
|
|
|
|
if is_visible {
|
|
|
|
iconizable.delete()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
iconizable.clear_callback();
|
|
|
|
}
|
|
|
|
|
|
|
|
*iconizable = None;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn set_icon(
|
|
|
|
&self,
|
|
|
|
icon_builder: impl Into<IconBuilderType>,
|
|
|
|
is_visible: bool,
|
|
|
|
) -> Result<()> {
|
|
|
|
let mut iconizable = self.iconizable.lock().unwrap();
|
|
|
|
|
|
|
|
match iconizable.as_ref() {
|
|
|
|
Some(iconizable) => iconizable.set_icon(icon_builder)?,
|
|
|
|
None => {
|
|
|
|
let new_iconizable = Iconizable::new(
|
|
|
|
self.framable.clone(),
|
|
|
|
icon_builder,
|
|
|
|
self.positioning.clone(),
|
|
|
|
)?;
|
|
|
|
|
|
|
|
new_iconizable.set_margin(self.margin.load(SeqCst))?;
|
|
|
|
|
|
|
|
if self.framable.is_framed() {
|
|
|
|
new_iconizable.update_frame()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
new_iconizable.set_ui_layer(self.framable.ui_layer());
|
|
|
|
|
|
|
|
if is_visible {
|
|
|
|
new_iconizable.add()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
*iconizable = Some(new_iconizable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn set_margin(&self, margin: u32) -> Result<()> {
|
|
|
|
if self.framable.is_framed() {
|
|
|
|
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
|
|
|
iconizable.set_margin(margin)?;
|
|
|
|
iconizable.update_frame()?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.margin.store(margin, SeqCst);
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn icon(&self) -> Result<Option<Arc<Image>>> {
|
|
|
|
match self.iconizable.lock().unwrap().as_ref() {
|
|
|
|
Some(iconizable) => Ok(Some(iconizable.icon())),
|
|
|
|
None => Ok(None),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn enable(&self) -> Result<()> {
|
|
|
|
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
|
|
|
iconizable.add()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn disable(&self) -> Result<()> {
|
|
|
|
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
|
|
|
iconizable.delete()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn update_frame(&self) -> Result<()> {
|
|
|
|
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
|
|
|
iconizable.update_frame()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for IconizableWrapper {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
if let Some(iconizable) = self.iconizable.lock().unwrap().as_ref() {
|
|
|
|
iconizable.clear_callback();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|