Add fill type concept

This commit is contained in:
hodasemi 2024-04-23 15:31:52 +02:00
parent 8731bf1f7e
commit ed3c470716
12 changed files with 170 additions and 52 deletions

View file

@ -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<FillTypeInfo>,
pub selected: Option<FillTypeInfo>,
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)
}

View file

@ -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));

View file

@ -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<u32>,
pub background_type: Option<FillTypeInfo>,
background_fill_type: DisplayableFillType,
pub text_ratio: Option<f32>,
pub text: RwLock<String>,
@ -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)
}
}

View file

@ -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!(

View file

@ -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!(

View file

@ -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!(

View file

@ -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)?)

View file

@ -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<FillTypeInfo>,
background_fill_type: DisplayableFillType,
pub parent: Weak<GridInfo>,
}
@ -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)
}
}

View file

@ -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<DisplayableFillType> {
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),
},
}
}

View file

@ -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,
)),
},
)?;

View file

@ -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<Color> for FillTypeInfo {
@ -21,27 +24,27 @@ impl From<Color> for FillTypeInfo {
}
}
impl From<String> 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<AssetPath> 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<Framable>, fill_type_info: FillTypeInfo) -> Result<Self> {
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<FillTypeInfo> 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,

View file

@ -33,6 +33,12 @@ impl From<ElementDescriptor> 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<Framable>,
@ -42,6 +48,7 @@ pub struct Displayable {
buffer: Arc<Buffer<TexturedVertex>>,
displayable_type: RwLock<DisplayableType>,
fill_type: DisplayableFillType,
ui_layer: AtomicI32,
@ -66,6 +73,7 @@ impl Displayable {
pub fn new(
framable: Arc<Framable>,
displayable_type: impl Into<DisplayableType>,
fill_type: DisplayableFillType,
) -> Result<Arc<Self>> {
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 {