generated from 2ndbeam/bevy-template
ui: Buggy 'natural' item dragging
- Items are now placed relative to cursor instead of upper left corner - Bug: after item drop all hovered slots are cleared and you cannot drag and drop item right away
This commit is contained in:
parent
337986d2b9
commit
3fdfa4a4ad
2 changed files with 41 additions and 9 deletions
|
|
@ -27,7 +27,10 @@ pub struct UiItem(pub Entity);
|
||||||
pub struct HoveredItem;
|
pub struct HoveredItem;
|
||||||
|
|
||||||
#[derive(Component, Reflect)]
|
#[derive(Component, Reflect)]
|
||||||
pub struct DraggedItem(pub Item);
|
pub struct HoveredSlot;
|
||||||
|
|
||||||
|
#[derive(Component, Reflect)]
|
||||||
|
pub struct DraggedItem(pub Item, pub UVec2);
|
||||||
|
|
||||||
fn ui_item_node_data(item: &Item) -> (Val, Val, Val, Val, UiTransform) {
|
fn ui_item_node_data(item: &Item) -> (Val, Val, Val, Val, UiTransform) {
|
||||||
match item.rotated {
|
match item.rotated {
|
||||||
|
|
@ -63,9 +66,21 @@ fn reset_slots_colors(query: Query<&mut ImageNode, With<UiInventorySlot>>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_slot_over(e: On<Pointer<Over>>, mut query: Query<&mut ImageNode, With<UiInventorySlot>>) {
|
fn on_slot_over(
|
||||||
if let Ok(mut image) = query.get_mut(e.event_target()) {
|
e: On<Pointer<Over>>,
|
||||||
|
mut commands: Commands,
|
||||||
|
mut image_query: Query<&mut ImageNode, With<UiInventorySlot>>,
|
||||||
|
hovered_slots: Query<Entity, With<HoveredSlot>>,
|
||||||
|
has_dragged_item: Option<Single<(), With<DraggedItem>>>,
|
||||||
|
) {
|
||||||
|
if let Ok(mut image) = image_query.get_mut(e.event_target()) {
|
||||||
image.color = Color::WHITE.darker(0.3);
|
image.color = Color::WHITE.darker(0.3);
|
||||||
|
};
|
||||||
|
for slot_id in hovered_slots {
|
||||||
|
commands.entity(slot_id).remove::<HoveredSlot>();
|
||||||
|
}
|
||||||
|
if has_dragged_item.is_none() {
|
||||||
|
commands.entity(e.event_target()).insert(HoveredSlot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,13 +119,19 @@ fn on_item_drag_start(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
ui_query: Query<&UiItem, With<HoveredItem>>,
|
ui_query: Query<&UiItem, With<HoveredItem>>,
|
||||||
item_query: Query<&Item>,
|
item_query: Query<&Item>,
|
||||||
|
hovered_slot: Single<&UiInventorySlot, With<HoveredSlot>>
|
||||||
) {
|
) {
|
||||||
if let Ok(ui_item) = ui_query.get(e.event_target()) {
|
if let Ok(ui_item) = ui_query.get(e.event_target()) {
|
||||||
let Ok(item) = item_query.get(ui_item.0) else {
|
let Ok(item) = item_query.get(ui_item.0) else {
|
||||||
error!("UiItem {} is pointing to non-existing Item", e.event_target());
|
error!("UiItem {} is pointing to non-existing Item", e.event_target());
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
commands.entity(e.event_target()).insert(DraggedItem(item.clone()));
|
let Some(item_position) = item.position else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let slot_position = hovered_slot.0;
|
||||||
|
let diff = slot_position - item_position;
|
||||||
|
commands.entity(e.event_target()).insert(DraggedItem(item.clone(), diff));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,6 +159,7 @@ fn on_item_drag_drop(
|
||||||
ui_inventory_query: Query<&UiInventory>,
|
ui_inventory_query: Query<&UiInventory>,
|
||||||
mut item_query: Query<&mut Item>,
|
mut item_query: Query<&mut Item>,
|
||||||
slot_query: Query<(&ChildOf, &UiInventorySlot, Option<&Children>)>,
|
slot_query: Query<(&ChildOf, &UiInventorySlot, Option<&Children>)>,
|
||||||
|
slot_id_query: Query<(Entity, &UiInventorySlot, &ChildOf), With<UiInventorySlot>>,
|
||||||
inventory_query: Query<(&Inventory, Option<&Children>)>,
|
inventory_query: Query<(&Inventory, Option<&Children>)>,
|
||||||
) {
|
) {
|
||||||
let Ok((ui_item_entity, UiItem(item_entity), mut dragged_item, node, ui_transform)) = ui_item_query.get_mut(event.dropped) else {
|
let Ok((ui_item_entity, UiItem(item_entity), mut dragged_item, node, ui_transform)) = ui_item_query.get_mut(event.dropped) else {
|
||||||
|
|
@ -161,16 +183,25 @@ fn on_item_drag_drop(
|
||||||
None => &[],
|
None => &[],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let actual_position = new_position.as_ivec2() - dragged_item.1.as_ivec2();
|
||||||
|
info!("{actual_position:?}");
|
||||||
let temp_item = &mut dragged_item.0;
|
let temp_item = &mut dragged_item.0;
|
||||||
temp_item.position = Some(*new_position);
|
if actual_position.is_negative_bitmask() == 0 {
|
||||||
|
temp_item.position = Some(actual_position.as_uvec2());
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some((slot_id, _, _)) = slot_id_query.iter().find(|(_, slot_pos, slot_parent_id)| slot_pos.0 == temp_item.position.unwrap() && slot_parent_id == &slot_parent) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
if inventory.can_replace(item_query.as_readonly(), items, *item_entity, temp_item) {
|
if inventory.can_replace(item_query.as_readonly(), items, *item_entity, temp_item) {
|
||||||
let mut item = item_query.get_mut(*item_entity).unwrap();
|
let mut item = item_query.get_mut(*item_entity).unwrap();
|
||||||
item.position = temp_item.position;
|
item.position = temp_item.position;
|
||||||
item.size = temp_item.size;
|
item.size = temp_item.size;
|
||||||
item.rotated = temp_item.rotated;
|
item.rotated = temp_item.rotated;
|
||||||
commands.entity(ui_item_entity).insert(ChildOf(event.event_target()));
|
commands.entity(ui_item_entity).insert(ChildOf(slot_id));
|
||||||
commands.entity(*item_entity).insert(ChildOf(*inventory_id));
|
commands.entity(*item_entity).insert(ChildOf(*inventory_id));
|
||||||
|
commands.entity(slot_id).insert(HoveredSlot);
|
||||||
update_ui_node(item.as_ref(), node, ui_transform);
|
update_ui_node(item.as_ref(), node, ui_transform);
|
||||||
} else {
|
} else {
|
||||||
if let Ok(item) = item_query.get(*item_entity) {
|
if let Ok(item) = item_query.get(*item_entity) {
|
||||||
|
|
@ -202,6 +233,7 @@ pub fn on_ui_rotate(
|
||||||
let (was_rotated, item) = match maybe_dragged {
|
let (was_rotated, item) = match maybe_dragged {
|
||||||
Some(mut temp_item) => {
|
Some(mut temp_item) => {
|
||||||
temp_item.0.rotate();
|
temp_item.0.rotate();
|
||||||
|
temp_item.1 = uvec2(temp_item.1.y, temp_item.1.x);
|
||||||
(true, Some(temp_item.0.clone()))
|
(true, Some(temp_item.0.clone()))
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,7 @@ mod inventory {
|
||||||
inventory_query: Query<(&Inventory, &Children)>,
|
inventory_query: Query<(&Inventory, &Children)>,
|
||||||
) {
|
) {
|
||||||
let (inventory, children) = inventory_query.single().unwrap();
|
let (inventory, children) = inventory_query.single().unwrap();
|
||||||
let (replacable_id, DraggedItem(replacing_item), RotatingMarker(assertion)) = replacable_item.single()
|
let (replacable_id, DraggedItem(replacing_item, _), RotatingMarker(assertion)) = replacable_item.single()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if *assertion {
|
if *assertion {
|
||||||
assert!(inventory.can_replace(item_query, children, replacable_id, replacing_item));
|
assert!(inventory.can_replace(item_query, children, replacable_id, replacing_item));
|
||||||
|
|
@ -369,7 +369,7 @@ mod inventory {
|
||||||
let system = world.register_system(replace_item);
|
let system = world.register_system(replace_item);
|
||||||
|
|
||||||
world.spawn(inventory())
|
world.spawn(inventory())
|
||||||
.with_child((item_a(), DraggedItem(item_c()), RotatingMarker(true)))
|
.with_child((item_a(), DraggedItem(item_c(), UVec2::ZERO), RotatingMarker(true)))
|
||||||
.with_child(item_b())
|
.with_child(item_b())
|
||||||
.with_child(item_d());
|
.with_child(item_d());
|
||||||
|
|
||||||
|
|
@ -383,7 +383,7 @@ mod inventory {
|
||||||
let system = world.register_system(replace_item);
|
let system = world.register_system(replace_item);
|
||||||
|
|
||||||
world.spawn(inventory())
|
world.spawn(inventory())
|
||||||
.with_child((item_a(), DraggedItem(item_c()), RotatingMarker(false)))
|
.with_child((item_a(), DraggedItem(item_c(), UVec2::ZERO), RotatingMarker(false)))
|
||||||
.with_child(item_b())
|
.with_child(item_b())
|
||||||
.with_child(item_c())
|
.with_child(item_c())
|
||||||
.with_child(item_d());
|
.with_child(item_d());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue