equipment ui layout
Guide for equipment ui layout
Equipment UI Layout
Design
Side-by-side layout with equipment slots on the left and inventory grid on the right.
┌────────────────────────────────────────┐
│ Equipment │ Backpack │
│ ───────── │ ──────── │
│ Head: [Item] │ [▪][▪][▪][▪] │
│ Cape: [Empty] │ [▪][▪][▪][▪] │
│ Neck: [Item] │ [▪][▪][▪][▪] │
│ Weapon: [Item] │ [▪][▪][▪][▪] │
│ Body: [Item] │ [▪][▪][▪][▪] │
│ Shield: [Empty]│ [▪][▪][▪][▪] │
│ Legs: [Item] │ [▪][▪][▪][▪] │
│ Hands: [Empty] │ │
│ Feet: [Item] │ │
│ Ring: [Empty] │ │
│ Ammo: [Item] │ │
└────────────────────────────────────────┘Implementation
Updated Function Signature
File:
src/systems/ui/inventory_ui.rspub fn render_inventory_tab(
ui: &mut egui::Ui,
player_entity: Entity,
inventory_query: &Query<&Inventory>,
equipment_query: &Query<&Equipment>, // NEW
use_events: &mut EventWriter<UseItemEvent>,
unequip_events: &mut EventWriter<UnequipItemEvent>, // NEW
)Layout Structure
ui.horizontal(|ui| {
// LEFT: Equipment Panel
ui.vertical(|ui| {
ui.label(egui::RichText::new("Equipment").strong());
ui.separator();
if let Some(equip) = equipment {
render_equipment_slots(ui, equip, player_entity, unequip_events);
}
});
ui.separator();
// RIGHT: Inventory Panel
ui.vertical(|ui| {
ui.label(egui::RichText::new("Backpack").strong());
ui.separator();
egui::ScrollArea::vertical().show(ui, |ui| {
egui::Grid::new("inventory_grid")
.spacing(egui::vec2(8.0, 8.0))
.min_col_width(40.0)
.show(ui, |ui| {
for (i, slot) in inventory.items.iter().enumerate() {
render_inventory_slot(ui, slot, i, player_entity, use_events);
if (i + 1) % 4 == 0 { ui.end_row(); }
}
});
});
});
});Equipment Slots Rendering
fn render_equipment_slots(
ui: &mut egui::Ui,
equip: &Equipment,
player_entity: Entity,
unequip_events: &mut EventWriter<UnequipItemEvent>,
) {
let slot_size = egui::vec2(32.0, 32.0);
let render_slot = |ui: &mut egui::Ui, name: &str, slot: &Option<ItemSlot>, slot_id: &str| {
ui.horizontal(|ui| {
ui.label(format!("{}: ", name));
let btn_text = if let Some(item) = slot {
format!("{}", item.id.0) // TODO: Use item name from GameData
} else {
"Empty".to_string()
};
let btn = ui.add(egui::Button::new(btn_text).min_size(slot_size));
if let Some(_item) = slot {
if btn.clicked() {
unequip_events.send(UnequipItemEvent {
entity: player_entity,
slot: slot_id.to_string(),
});
}
btn.on_hover_text("Click to unequip");
}
});
};
// Render all slots
render_slot(ui, "Head", &equip.head, "head");
render_slot(ui, "Cape", &equip.cape, "cape");
render_slot(ui, "Neck", &equip.neck, "neck");
render_slot(ui, "Weapon", &equip.weapon, "weapon");
render_slot(ui, "Body", &equip.body, "body");
render_slot(ui, "Shield", &equip.shield, "shield");
render_slot(ui, "Legs", &equip.legs, "legs");
render_slot(ui, "Hands", &equip.hands, "hands");
render_slot(ui, "Feet", &equip.feet, "feet");
render_slot(ui, "Ring", &equip.ring, "ring");
render_slot(ui, "Ammo", &equip.ammo, "ammo");
}Inventory Slot Context Menu
response.context_menu(|ui| {
ui.label(format!("Item: {}", item.id.0));
if ui.button("Use / Equip").clicked() { // Changed from "Use"
use_events.send(UseItemEvent {
entity: player_entity,
item: item.id,
});
ui.close_menu();
}
if ui.button("Drop").clicked() {
// TODO: Drop item logic
ui.close_menu();
}
});UI Integration
File:
src/systems/ui/mod.rs1. Add Equipment Query to UiParams
#[derive(bevy::ecs::system::SystemParam)]
pub struct UiParams<'w, 's> {
// ... existing fields
pub equipment_q: Query<'w, 's, &'static crate::systems::player::equipment::Equipment>,
}2. Add UnequipItemEvent Writer
fn ui_main_layout(
// ... existing params
mut unequip_item_writer: EventWriter<crate::systems::player::equipment::UnequipItemEvent>,
) {
// ... unpack params
let equipment_q = params.equipment_q;
// ... in Inventory tab case:
UiTab::Inventory => {
if let Ok((player_entity, _, _)) = player_q.get_single() {
inventory_ui::render_inventory_tab(
ui,
player_entity,
&inventory_q,
&equipment_q, // NEW
&mut use_item_writer,
&mut unequip_item_writer // NEW
);
}
}
}Future Enhancements
- Item Icons: Replace item IDs with actual icons from GameData
- Drag-and-Drop: Allow dragging items from inventory to equipment slots
- Stat Preview: Show stat changes when hovering over equippable items
- Visual Feedback: Highlight compatible equipment slots when selecting an item
- Equipment Sets: Show set bonuses when wearing matching items