use bevy::{ ecs::relationship::RelatedSpawner, prelude::*, ui_widgets::{ ControlOrientation, CoreScrollbarThumb, Scrollbar, }, }; use super::*; pub fn ui_manager_bundle(children: Vec, aligned_left: bool) -> impl Bundle { let left = if aligned_left { Val::ZERO } else { percent(50.) }; ( UiInventoryManager, Node { position_type: PositionType::Absolute, left, width: percent(50.), height: percent(100.), scrollbar_width: 8., display: Display::Grid, grid_template_columns: vec![RepeatedGridTrack::flex(1, 1.), RepeatedGridTrack::auto(1)], grid_template_rows: vec![RepeatedGridTrack::flex(1, 1.), RepeatedGridTrack::auto(1)], ..default() }, Pickable::IGNORE, GlobalZIndex::default(), Children::spawn(SpawnWith(move |parent: &mut RelatedSpawner| { let scroll_area_id = parent.spawn(( Node { width: percent(100.), height: percent(100.), display: Display::Flex, flex_direction: FlexDirection::Column, align_items: AlignItems::Center, justify_content: JustifyContent::SpaceAround, overflow: Overflow::scroll_y(), ..default() }, ScrollPosition(Vec2::ZERO), )).add_children(children.as_slice()).id(); parent.spawn(( Node { min_width: px(8), grid_row: GridPlacement::start(1), grid_column: GridPlacement::start(2), ..default() }, Scrollbar { orientation: ControlOrientation::Vertical, target: scroll_area_id, min_thumb_length: 8.0, }, BackgroundColor(Color::hsl(0., 0., 0.5)), children![( Node { position_type: PositionType::Absolute, border_radius: BorderRadius::all(px(4.)), ..default() }, BackgroundColor(Color::hsl(0., 0., 0.3)), CoreScrollbarThumb, )], )); })), ) } pub fn ui_inventory_bundle( inventory: &Inventory, inventory_entity: Entity, ) -> impl Bundle { ( UiInventory(inventory_entity), Node { align_self: AlignSelf::Stretch, align_content: AlignContent::Center, display: Display::Grid, width: percent(100.), aspect_ratio: Some(inventory.size.x as f32 / inventory.size.y as f32), grid_auto_columns: vec![GridTrack::percent(100. / inventory.size.x as f32)], grid_auto_rows: vec![GridTrack::percent(100. / inventory.size.y as f32)], ..default() }, Pickable::IGNORE, GlobalZIndex::default(), Name::new(format!("UiInventory ({}x{})", inventory.size.x, inventory.size.y)), ) } pub fn inventory_slot_bundle(x: u32, y: u32, image: Handle) -> impl Bundle { ( UiInventorySlot(UVec2::new(x, y)), ImageNode { color: Color::WHITE, image, image_mode: NodeImageMode::Stretch, ..default() }, Node { width: percent(100.), height: percent(100.), grid_column: GridPlacement::start(x as i16 + 1), grid_row: GridPlacement::start(y as i16 + 1), aspect_ratio: Some(1.), ..default() }, Pickable { should_block_lower: true, is_hoverable: true, }, GlobalZIndex(1), BackgroundColor::DEFAULT, Name::new(format!("UiInventorySlot({x},{y})")), ) } pub fn ui_item_bundle(item: &Item, item_entity: Entity, image: Handle) -> impl Bundle { let (left, top, min_width, min_height, ui_transform) = ui_item_node_data(item); ( UiItem(item_entity), ImageNode { image, image_mode: NodeImageMode::Stretch, ..default() }, Node { left, top, min_width, min_height, ..default() }, BackgroundColor(Color::hsla(0., 0., 0., 0.5)), ui_transform, GlobalZIndex(2), Pickable { should_block_lower: false, is_hoverable: true, }, Name::new(format!("UiItem ({},{})", item.position.unwrap_or_default().x, item.position.unwrap_or_default().y, )), ) }