Skip to content
Snippets Groups Projects
inset_icon.rs 2.13 KiB
Newer Older
Louis's avatar
Louis committed
use bevy::prelude::*;
use kayak_ui::prelude::*;
use kayak_ui::widgets::{KImage, KImageBundle, TextureAtlasBundle, TextureAtlasProps};

use crate::parent_widget;
use crate::theme::ThemeProvider;
use crate::types::IconContent;
use crate::*;

#[derive(Clone, Component, PartialEq)]
pub struct InsetIconProps {
	pub image: IconContent,
	pub size: f32,
}

impl Default for InsetIconProps {
	fn default() -> Self {
		Self {
			image: IconContent::None,
			size: 48.0,
		}
	}
}

impl Widget for InsetIconProps {}

parent_widget!(InsetIconProps => InsetIconWidget);

pub fn render_inset_icon_widget(
	In(entity): In<Entity>,
	widget_context: Res<KayakWidgetContext>,
	mut commands: Commands,
	mut query: Query<(&InsetIconProps, &mut ComputedStyles, &KStyle)>,
	theme_provider: ThemeProvider,
	atlass_layout: Res<Assets<TextureAtlasLayout>>,
) -> bool {
	let parent_id = Some(entity);

	if let Ok((props, mut computed, style)) = query.get_mut(entity) {
		*computed = KStyle {
			render_command: value(RenderCommand::Layout),
			min_height: px(32.0),
			min_width: px(32.0),
			height: px(props.size),
			width: px(props.size),
			padding: value(Edge::all(Units::Stretch(0.0))),
			..Default::default()
		}
		.with_style(style)
		.into();

		let image_styles = KStyle {
			width: stretch(1.0),
			height: stretch(1.0),
			..Default::default()
		};

		match &props.image {
			IconContent::Image(name) => {
				let handle = theme_provider.get_image(name).unwrap();

				rsx! {
					<KImageBundle
						image={KImage(handle.clone_weak())}
						styles={image_styles}
					/>
				};
			}
			IconContent::Atlas(name, index) => {
				let atlas_handle = theme_provider.get_atlas(name).unwrap();
				let image_handle = theme_provider.get_image(name).unwrap();

				if let Some(atlas) = atlass_layout.get(atlas_handle) {
					let rect = atlas.textures[*index];
					let position = rect.min;
					let tile_size = rect.max - rect.min;

					rsx! {
						<TextureAtlasBundle
							atlas={TextureAtlasProps {
								tile_size,
								position,
								handle: image_handle.clone_weak(),
							}}
							styles={image_styles}
						/>
					};
				}
			}
			IconContent::None => {}
		}
	}

	true
}