From ed3c4707167c328844f795e6b9f4d80ba26f2c50 Mon Sep 17 00:00:00 2001 From: hodasemi Date: Tue, 23 Apr 2024 15:31:52 +0200 Subject: [PATCH] Add fill type concept --- src/builder/validator/buttoninfo.rs | 38 +++++++++++++-- src/builder/validator/gridinfo.rs | 8 ++-- src/builder/validator/iconinfo.rs | 24 +++++++++- src/builder/validator/labelinfo.rs | 4 +- src/builder/validator/multi_line_labelinfo.rs | 4 +- .../validator/multi_line_text_field_info.rs | 4 +- src/builder/validator/progressbar_info.rs | 6 +-- src/builder/validator/textfieldinfo.rs | 24 +++++++++- src/builder/validator/validator.rs | 19 ++++++-- src/elements/button.rs | 13 +++-- src/elements/fill_type.rs | 47 ++++++++++--------- src/guihandler/gui/displayable.rs | 31 ++++++++++-- 12 files changed, 170 insertions(+), 52 deletions(-) diff --git a/src/builder/validator/buttoninfo.rs b/src/builder/validator/buttoninfo.rs index 7cbdc1b..719ea60 100644 --- a/src/builder/validator/buttoninfo.rs +++ b/src/builder/validator/buttoninfo.rs @@ -1,3 +1,4 @@ +use crate::guihandler::gui::displayable::DisplayableFillType; use crate::prelude::*; use anyhow::Result; use utilities::prelude::*; @@ -13,7 +14,8 @@ use std::str::from_utf8; use std::sync::{Arc, RwLock, Weak}; use super::validator::{ - cow_to_button_select_mode, cow_to_fill_type, cow_to_str, cow_to_text_alignment, str_into, + cow_to_button_select_mode, cow_to_fill_type, cow_to_fill_type_info, cow_to_str, + cow_to_text_alignment, str_into, }; #[cfg(feature = "audio")] @@ -48,6 +50,8 @@ pub struct ButtonInfo { pub normal: Option, pub selected: Option, + background_fill_type: DisplayableFillType, + #[cfg(feature = "audio")] pub click_sound: AssetPath, @@ -89,6 +93,7 @@ impl ButtonInfo { normal: Self::find_menu_button(grid), selected: Self::find_menu_button_selected(grid), + background_fill_type: DisplayableFillType::Expand, #[cfg(feature = "audio")] click_sound: match Self::find_click_sound(grid) { @@ -128,8 +133,11 @@ impl ButtonInfo { b"y_slot" => button_info.y_slot.set(str_into(attribute.value)?), b"x_size" => button_info.x_dim = str_into(attribute.value)?, b"y_size" => button_info.y_dim = str_into(attribute.value)?, - b"normal" => button_info.normal = Some(cow_to_fill_type(attribute.value)), - b"selected" => button_info.selected = Some(cow_to_fill_type(attribute.value)), + b"normal" => button_info.normal = Some(cow_to_fill_type_info(attribute.value)), + b"selected" => button_info.selected = Some(cow_to_fill_type_info(attribute.value)), + b"fill_type" => { + button_info.background_fill_type = cow_to_fill_type(attribute.value)?; + } #[cfg(feature = "audio")] b"click_sound" => button_info.click_sound = cow_to_path(attribute.value), @@ -169,6 +177,30 @@ impl ButtonInfo { } } + if let Some(background_type) = &mut button_info.normal { + match background_type { + FillTypeInfo::Image(_, fill_type) => { + *fill_type = button_info.background_fill_type; + } + FillTypeInfo::Color(_) => (), + FillTypeInfo::Element(_, fill_type) => { + *fill_type = button_info.background_fill_type; + } + } + } + + if let Some(background_type) = &mut button_info.selected { + match background_type { + FillTypeInfo::Image(_, fill_type) => { + *fill_type = button_info.background_fill_type; + } + FillTypeInfo::Color(_) => (), + FillTypeInfo::Element(_, fill_type) => { + *fill_type = button_info.background_fill_type; + } + } + } + Ok(button_info) } diff --git a/src/builder/validator/gridinfo.rs b/src/builder/validator/gridinfo.rs index 50bc339..af6c15d 100644 --- a/src/builder/validator/gridinfo.rs +++ b/src/builder/validator/gridinfo.rs @@ -9,7 +9,7 @@ use std::sync::{RwLock, Weak}; use super::mandatory::Mandatory; use super::validator::{ - cow_to_fill_type, cow_to_path, cow_to_str, str_into, str_to_hori_align, str_to_vert_align, + cow_to_fill_type_info, cow_to_path, cow_to_str, str_into, str_to_hori_align, str_to_vert_align, }; pub struct GridInfo { @@ -108,13 +108,13 @@ impl GridInfo { .horizontal_alignment .set(str_to_hori_align(attribute.value)?), b"background" => { - grid_info.background_type = Some(cow_to_fill_type(attribute.value)) + grid_info.background_type = Some(cow_to_fill_type_info(attribute.value)) } b"button_normal" => { - grid_info.button_normal = Some(cow_to_fill_type(attribute.value)) + grid_info.button_normal = Some(cow_to_fill_type_info(attribute.value)) } b"button_selected" => { - grid_info.button_selected = Some(cow_to_fill_type(attribute.value)) + grid_info.button_selected = Some(cow_to_fill_type_info(attribute.value)) } b"click_sound" => { grid_info.click_sound = Some(cow_to_path(attribute.value)); diff --git a/src/builder/validator/iconinfo.rs b/src/builder/validator/iconinfo.rs index 5ed2f59..57415e9 100644 --- a/src/builder/validator/iconinfo.rs +++ b/src/builder/validator/iconinfo.rs @@ -1,3 +1,4 @@ +use crate::guihandler::gui::displayable::DisplayableFillType; use crate::prelude::*; use anyhow::Result; use assetpath::AssetPath; @@ -12,7 +13,9 @@ use std::{ sync::{Arc, RwLock, Weak}, }; -use super::validator::{cow_to_fill_type, cow_to_path, cow_to_str, str_into}; +use super::validator::{ + cow_to_fill_type, cow_to_fill_type_info, cow_to_path, cow_to_str, str_into, +}; pub struct IconInfo { pub id: String, @@ -27,6 +30,7 @@ pub struct IconInfo { pub margin: Option, pub background_type: Option, + background_fill_type: DisplayableFillType, pub text_ratio: Option, pub text: RwLock, @@ -53,6 +57,7 @@ impl IconInfo { margin: None, background_type: None, + background_fill_type: DisplayableFillType::Expand, text_ratio: None, text: RwLock::new(String::new()), @@ -73,7 +78,10 @@ impl IconInfo { b"icon" => icon_info.icon = Some(cow_to_path(attribute.value)), b"margin" => icon_info.margin = Some(str_into(attribute.value)?), b"background" => { - icon_info.background_type = Some(cow_to_fill_type(attribute.value)) + icon_info.background_type = Some(cow_to_fill_type_info(attribute.value)) + } + b"fill_type" => { + icon_info.background_fill_type = cow_to_fill_type(attribute.value)?; } b"text_color" => { let text = cow_to_str(attribute.value); @@ -89,6 +97,18 @@ impl IconInfo { } } + if let Some(background_type) = &mut icon_info.background_type { + match background_type { + FillTypeInfo::Image(_, fill_type) => { + *fill_type = icon_info.background_fill_type; + } + FillTypeInfo::Color(_) => (), + FillTypeInfo::Element(_, fill_type) => { + *fill_type = icon_info.background_fill_type; + } + } + } + Ok(icon_info) } } diff --git a/src/builder/validator/labelinfo.rs b/src/builder/validator/labelinfo.rs index a277935..0a67170 100644 --- a/src/builder/validator/labelinfo.rs +++ b/src/builder/validator/labelinfo.rs @@ -9,7 +9,7 @@ use std::convert::TryFrom; use std::str::from_utf8; use std::sync::{Arc, RwLock, Weak}; -use super::validator::{cow_to_fill_type, cow_to_str, cow_to_text_alignment, str_into}; +use super::validator::{cow_to_fill_type_info, cow_to_str, cow_to_text_alignment, str_into}; pub struct LabelInfo { pub id: String, @@ -72,7 +72,7 @@ impl LabelInfo { label_info.text_alignment = cow_to_text_alignment(attribute.value)? } b"background" => { - label_info.background_type = Some(cow_to_fill_type(attribute.value)); + label_info.background_type = Some(cow_to_fill_type_info(attribute.value)); } _ => { return Err(anyhow::Error::msg(format!( diff --git a/src/builder/validator/multi_line_labelinfo.rs b/src/builder/validator/multi_line_labelinfo.rs index d56952e..429eeb4 100644 --- a/src/builder/validator/multi_line_labelinfo.rs +++ b/src/builder/validator/multi_line_labelinfo.rs @@ -9,7 +9,7 @@ use std::convert::TryFrom; use std::str::from_utf8; use std::sync::{Arc, RwLock, Weak}; -use super::validator::{cow_to_fill_type, cow_to_str, cow_to_text_alignment, str_into}; +use super::validator::{cow_to_fill_type_info, cow_to_str, cow_to_text_alignment, str_into}; pub struct MultiLineLabelInfo { pub id: String, @@ -77,7 +77,7 @@ impl MultiLineLabelInfo { label_info.text_alignment = cow_to_text_alignment(attribute.value)? } b"background" => { - label_info.background_type = Some(cow_to_fill_type(attribute.value)); + label_info.background_type = Some(cow_to_fill_type_info(attribute.value)); } _ => { return Err(anyhow::Error::msg(format!( diff --git a/src/builder/validator/multi_line_text_field_info.rs b/src/builder/validator/multi_line_text_field_info.rs index 96a1b31..f0870b4 100644 --- a/src/builder/validator/multi_line_text_field_info.rs +++ b/src/builder/validator/multi_line_text_field_info.rs @@ -9,7 +9,7 @@ use std::convert::TryFrom; use std::str::from_utf8; use std::sync::{Arc, RwLock, Weak}; -use super::validator::{cow_to_fill_type, cow_to_str, cow_to_text_alignment, str_into}; +use super::validator::{cow_to_fill_type_info, cow_to_str, cow_to_text_alignment, str_into}; pub struct MultiLineTextFieldInfo { pub id: String, @@ -77,7 +77,7 @@ impl MultiLineTextFieldInfo { label_info.text_alignment = cow_to_text_alignment(attribute.value)? } b"background" => { - label_info.background_type = Some(cow_to_fill_type(attribute.value)); + label_info.background_type = Some(cow_to_fill_type_info(attribute.value)); } _ => { return Err(anyhow::Error::msg(format!( diff --git a/src/builder/validator/progressbar_info.rs b/src/builder/validator/progressbar_info.rs index 172dec8..5578aa1 100644 --- a/src/builder/validator/progressbar_info.rs +++ b/src/builder/validator/progressbar_info.rs @@ -12,7 +12,7 @@ use std::{ }; use super::validator::{ - cow_to_fill_type, cow_to_grow_direction, cow_to_str, cow_to_text_alignment, str_into, + cow_to_fill_type_info, cow_to_grow_direction, cow_to_str, cow_to_text_alignment, str_into, }; pub struct ProgressBarInfo { @@ -72,10 +72,10 @@ impl ProgressBarInfo { b"x_size" => progress_bar_info.x_dim = str_into(attribute.value)?, b"y_size" => progress_bar_info.y_dim = str_into(attribute.value)?, b"background" => { - progress_bar_info.background = Some(cow_to_fill_type(attribute.value)) + progress_bar_info.background = Some(cow_to_fill_type_info(attribute.value)) } b"foreground" => { - progress_bar_info.foreground = Some(cow_to_fill_type(attribute.value)) + progress_bar_info.foreground = Some(cow_to_fill_type_info(attribute.value)) } b"direction" => { progress_bar_info.direction = Some(cow_to_grow_direction(attribute.value)?) diff --git a/src/builder/validator/textfieldinfo.rs b/src/builder/validator/textfieldinfo.rs index 6b626bb..37b75f1 100644 --- a/src/builder/validator/textfieldinfo.rs +++ b/src/builder/validator/textfieldinfo.rs @@ -1,3 +1,4 @@ +use crate::guihandler::gui::displayable::DisplayableFillType; use crate::prelude::*; use anyhow::Result; use utilities::prelude::*; @@ -9,7 +10,9 @@ use std::convert::TryFrom; use std::str::from_utf8; use std::sync::{Arc, RwLock, Weak}; -use super::validator::{cow_to_fill_type, cow_to_str, cow_to_text_alignment, str_into}; +use super::validator::{ + cow_to_fill_type, cow_to_fill_type_info, cow_to_str, cow_to_text_alignment, str_into, +}; pub struct TextFieldInfo { pub id: String, @@ -26,6 +29,7 @@ pub struct TextFieldInfo { pub text_alignment: TextAlignment, pub background_type: Option, + background_fill_type: DisplayableFillType, pub parent: Weak, } @@ -50,6 +54,7 @@ impl TextFieldInfo { text_alignment: TextAlignment::default(), background_type: None, + background_fill_type: DisplayableFillType::Expand, parent: Arc::downgrade(grid), }; @@ -69,7 +74,10 @@ impl TextFieldInfo { } b"text_ratio" => text_field_info.text_ratio = Some(str_into(attribute.value)?), b"background" => { - text_field_info.background_type = Some(cow_to_fill_type(attribute.value)); + text_field_info.background_type = Some(cow_to_fill_type_info(attribute.value)); + } + b"fill_type" => { + text_field_info.background_fill_type = cow_to_fill_type(attribute.value)?; } b"text_alignment" => { text_field_info.text_alignment = cow_to_text_alignment(attribute.value)? @@ -83,6 +91,18 @@ impl TextFieldInfo { } } + if let Some(background_type) = &mut text_field_info.background_type { + match background_type { + FillTypeInfo::Image(_, fill_type) => { + *fill_type = text_field_info.background_fill_type; + } + FillTypeInfo::Color(_) => (), + FillTypeInfo::Element(_, fill_type) => { + *fill_type = text_field_info.background_fill_type; + } + } + } + Ok(text_field_info) } } diff --git a/src/builder/validator/validator.rs b/src/builder/validator/validator.rs index e73c163..9420cbc 100644 --- a/src/builder/validator/validator.rs +++ b/src/builder/validator/validator.rs @@ -1,4 +1,6 @@ +use crate::guihandler::gui::displayable::DisplayableFillType; use crate::prelude::*; +use anyhow::anyhow; use anyhow::{Context, Result}; use assetpath::AssetPath; use serde_json::from_str; @@ -510,14 +512,25 @@ where } } -pub fn cow_to_fill_type<'a>(cow: Cow<'a, [u8]>) -> FillTypeInfo { +pub fn cow_to_fill_type<'a>(cow: Cow<'a, [u8]>) -> Result { + let text = cow_to_str(cow); + + match text.as_str() { + "expand" => Ok(DisplayableFillType::Expand), + "square" => Ok(DisplayableFillType::Square), + + _ => Err(anyhow!("failed parsing DisplayableFillType from {text}")), + } +} + +pub fn cow_to_fill_type_info<'a>(cow: Cow<'a, [u8]>) -> FillTypeInfo { let text = cow_to_str(cow); match Color::try_from(text.as_str()) { Ok(color) => FillTypeInfo::Color(color), Err(_) => match from_str(text.as_str()) { - Ok(descriptor) => FillTypeInfo::Element(descriptor), - Err(_) => FillTypeInfo::Image(AssetPath::from(text)), + Ok(descriptor) => FillTypeInfo::Element(descriptor, DisplayableFillType::Expand), + Err(_) => FillTypeInfo::Image(AssetPath::from(text), DisplayableFillType::Expand), }, } } diff --git a/src/elements/button.rs b/src/elements/button.rs index 72f9236..45f184e 100644 --- a/src/elements/button.rs +++ b/src/elements/button.rs @@ -1,5 +1,6 @@ use crate::{ - builder::validator::buttoninfo::ButtonInfo, guihandler::gui::iconizable::IconizablePositioning, + builder::validator::buttoninfo::ButtonInfo, + guihandler::gui::{displayable::DisplayableFillType, iconizable::IconizablePositioning}, prelude::*, }; @@ -112,7 +113,10 @@ impl ButtonBuilder { framable.clone(), match self.normal { Some(info) => info, - None => FillTypeInfo::from(gui_handler.menu_button().clone()), + None => FillTypeInfo::from(( + gui_handler.menu_button().clone(), + DisplayableFillType::Expand, + )), }, )?; @@ -120,7 +124,10 @@ impl ButtonBuilder { framable.clone(), match self.selected { Some(info) => info, - None => FillTypeInfo::from(gui_handler.menu_button_selected().clone()), + None => FillTypeInfo::from(( + gui_handler.menu_button_selected().clone(), + DisplayableFillType::Expand, + )), }, )?; diff --git a/src/elements/fill_type.rs b/src/elements/fill_type.rs index 2c5bce2..f7bbc1c 100644 --- a/src/elements/fill_type.rs +++ b/src/elements/fill_type.rs @@ -1,4 +1,7 @@ -use crate::{guihandler::gui::displayable::DisplayableType, prelude::*}; +use crate::{ + guihandler::gui::displayable::{DisplayableFillType, DisplayableType}, + prelude::*, +}; use anyhow::Result; use assetpath::AssetPath; use utilities::prelude::*; @@ -10,9 +13,9 @@ use std::sync::{ #[derive(Debug, Clone)] pub enum FillTypeInfo { - Image(AssetPath), + Image(AssetPath, DisplayableFillType), Color(Color), - Element(ElementDescriptor), + Element(ElementDescriptor, DisplayableFillType), } impl From for FillTypeInfo { @@ -21,27 +24,27 @@ impl From for FillTypeInfo { } } -impl From for FillTypeInfo { - fn from(s: String) -> Self { - Self::Image(AssetPath::from(s)) +impl From<(String, DisplayableFillType)> for FillTypeInfo { + fn from((s, fill_type): (String, DisplayableFillType)) -> Self { + Self::Image(AssetPath::from(s), fill_type) } } -impl From<&str> for FillTypeInfo { - fn from(s: &str) -> Self { - Self::Image(AssetPath::from(s)) +impl From<(&str, DisplayableFillType)> for FillTypeInfo { + fn from((s, fill_type): (&str, DisplayableFillType)) -> Self { + Self::Image(AssetPath::from(s), fill_type) } } -impl From<&String> for FillTypeInfo { - fn from(s: &String) -> Self { - Self::Image(AssetPath::from(s.as_str())) +impl From<(&String, DisplayableFillType)> for FillTypeInfo { + fn from((s, fill_type): (&String, DisplayableFillType)) -> Self { + Self::Image(AssetPath::from(s.as_str()), fill_type) } } -impl From for FillTypeInfo { - fn from(assetpath: AssetPath) -> Self { - Self::Image(assetpath) +impl From<(AssetPath, DisplayableFillType)> for FillTypeInfo { + fn from((assetpath, fill_type): (AssetPath, DisplayableFillType)) -> Self { + Self::Image(assetpath, fill_type) } } @@ -53,12 +56,12 @@ pub(crate) enum InnerFillType { impl InnerFillType { pub(crate) fn new(framable: Arc, fill_type_info: FillTypeInfo) -> Result { match fill_type_info { - FillTypeInfo::Element(descriptor) => Ok(InnerFillType::Image(Displayable::new( - framable, descriptor, + FillTypeInfo::Element(descriptor, fill_type) => Ok(InnerFillType::Image( + Displayable::new(framable, descriptor, fill_type)?, + )), + FillTypeInfo::Image(path, fill_type) => Ok(InnerFillType::Image(Displayable::new( + framable, path, fill_type, )?)), - FillTypeInfo::Image(path) => { - Ok(InnerFillType::Image(Displayable::new(framable, path)?)) - } FillTypeInfo::Color(color) => { Ok(InnerFillType::Color(Colorable::new(framable, color)?)) } @@ -152,13 +155,13 @@ impl FillType { impl PartialEq for FillType { fn eq(&self, info: &FillTypeInfo) -> bool { match (&self.inner, info) { - (InnerFillType::Image(inner_image), FillTypeInfo::Image(info_image)) => { + (InnerFillType::Image(inner_image), FillTypeInfo::Image(info_image, _)) => { match inner_image.inner_type() { DisplayableType::Path(path) => path == *info_image, DisplayableType::Descriptor(_) => false, } } - (InnerFillType::Image(inner_image), FillTypeInfo::Element(info_descriptor)) => { + (InnerFillType::Image(inner_image), FillTypeInfo::Element(info_descriptor, _)) => { match inner_image.inner_type() { DisplayableType::Path(_) => false, DisplayableType::Descriptor(descriptor) => descriptor == *info_descriptor, diff --git a/src/guihandler/gui/displayable.rs b/src/guihandler/gui/displayable.rs index 7ecd7b5..c44d301 100644 --- a/src/guihandler/gui/displayable.rs +++ b/src/guihandler/gui/displayable.rs @@ -33,6 +33,12 @@ impl From for DisplayableType { } } +#[derive(Debug, Clone, Copy)] +pub enum DisplayableFillType { + Expand, + Square, +} + /// `Displayable` gives the ability to display a texture as background image for an item pub struct Displayable { framable: Arc, @@ -42,6 +48,7 @@ pub struct Displayable { buffer: Arc>, displayable_type: RwLock, + fill_type: DisplayableFillType, ui_layer: AtomicI32, @@ -66,6 +73,7 @@ impl Displayable { pub fn new( framable: Arc, displayable_type: impl Into, + fill_type: DisplayableFillType, ) -> Result> { let descriptor_set = framable.gui_handler().image_descriptor_set()?; @@ -90,6 +98,7 @@ impl Displayable { buffer, displayable_type: RwLock::new(displayable_type), + fill_type, ui_layer: AtomicI32::new(0), @@ -236,11 +245,25 @@ impl Displayable { pub fn update_frame(&self) -> Result<()> { let mut frame = self.buffer.map_complete()?; - let x_start = self.framable.left() as f32; - let y_start = self.framable.top() as f32; + let mut x_start = self.framable.left() as f32; + let mut y_start = self.framable.top() as f32; - let width = (self.framable.right() - self.framable.left()) as f32; - let height = (self.framable.bottom() - self.framable.top()) as f32; + let mut width = (self.framable.right() - self.framable.left()) as f32; + let mut height = (self.framable.bottom() - self.framable.top()) as f32; + + if let DisplayableFillType::Square = self.fill_type { + if width > height { + let diff = width - height; + + x_start += diff * 0.5; + width = height; + } else if height > width { + let diff = height - width; + + y_start += diff * 0.5; + height = width; + } + } if let DisplayableType::Descriptor(descriptor) = &*self.displayable_type.read().unwrap() { if width > 0.0 && height > 0.0 {