updated example

This commit is contained in:
ickshonpe 2025-07-11 16:37:49 +01:00
parent cf5aac4938
commit f4aacc8583

View File

@ -4,11 +4,10 @@ use bevy::color::palettes::css::NAVY;
use bevy::color::palettes::css::RED; use bevy::color::palettes::css::RED;
use bevy::input::mouse::MouseMotion; use bevy::input::mouse::MouseMotion;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::window::PrimaryWindow;
#[derive(Component, Debug, Eq, PartialEq, Hash)] #[derive(Component, Debug, Eq, PartialEq, Hash)]
enum ValueLabel { enum ValueLabel {
TargetScaleFactor, RenderTargetScaleFactor,
UiScale, UiScale,
CombinedScaleFactor, CombinedScaleFactor,
MouseMotionSum, MouseMotionSum,
@ -60,7 +59,7 @@ fn setup(mut commands: Commands) {
)) ))
.with_children(|commands| { .with_children(|commands| {
for w in [ for w in [
ValueLabel::TargetScaleFactor, ValueLabel::RenderTargetScaleFactor,
ValueLabel::UiScale, ValueLabel::UiScale,
ValueLabel::CombinedScaleFactor, ValueLabel::CombinedScaleFactor,
ValueLabel::MouseMotionSum, ValueLabel::MouseMotionSum,
@ -132,14 +131,14 @@ fn setup(mut commands: Commands) {
GlobalZIndex(-1), GlobalZIndex(-1),
)) ))
.with_children(|commands| { .with_children(|commands| {
for x in 0..20 { for x in 0..30 {
commands commands
.spawn(Node { .spawn(Node {
flex_direction: FlexDirection::Column, flex_direction: FlexDirection::Column,
..Default::default() ..Default::default()
}) })
.with_children(|commands| { .with_children(|commands| {
for y in 0..20 { for y in 0..30 {
let color = if (x + y) % 2 == 1 { let color = if (x + y) % 2 == 1 {
NAVY.into() NAVY.into()
} else { } else {
@ -147,9 +146,9 @@ fn setup(mut commands: Commands) {
}; };
commands.spawn(( commands.spawn((
Node { Node {
width: Val::Px(300.), width: Val::Px(100.),
height: Val::Px(300.), height: Val::Px(100.),
min_height: Val::Px(300.), min_height: Val::Px(100.),
..Default::default() ..Default::default()
}, },
BackgroundColor(color), BackgroundColor(color),
@ -163,25 +162,20 @@ fn setup(mut commands: Commands) {
fn update( fn update(
mut mouse_motions: EventReader<MouseMotion>, mut mouse_motions: EventReader<MouseMotion>,
ui_scale: Res<UiScale>, ui_scale: Res<UiScale>,
window_query: Query<&Window, With<PrimaryWindow>>,
mut values: ResMut<DragValues>, mut values: ResMut<DragValues>,
mut watched_values_query: Query<(&ValueLabel, &mut TextSpan)>, mut watched_values_query: Query<(&ValueLabel, &mut TextSpan)>,
mut drag_node: Query<(&mut ComputedNode, &mut Node), With<DragNode>>, mut drag_node_query: Query<(&ComputedNode, &mut Node, &ComputedNodeTarget), With<DragNode>>,
mut scroll_position: Query<&mut ScrollPosition, With<ScrollableNode>>, mut scroll_position_query: Query<&mut ScrollPosition, With<ScrollableNode>>,
) { ) {
let Ok((computed_node, mut node, computed_target)) = drag_node_query.single_mut() else {
return;
};
for motion in mouse_motions.read() { for motion in mouse_motions.read() {
values.mouse_motion_sum += motion.delta; values.mouse_motion_sum += motion.delta;
} }
let target_scale_factor = window_query let current_scroll_position = scroll_position_query.single_mut().ok().map(|mut p| {
.single()
.map(|window| window.scale_factor())
.unwrap_or(1.);
let computed_node_size = drag_node.single().ok().unwrap().0.size();
let combined_scale_factor = target_scale_factor * ui_scale.0;
let scaled_distance = values.drag_distance / ui_scale.0;
let current_scroll_position = scroll_position.single_mut().ok().map(|mut p| {
let out = Vec2::new(p.x, p.y); let out = Vec2::new(p.x, p.y);
p.x = -values.drag_total.x; p.x = -values.drag_total.x;
p.y = -values.drag_total.y; p.y = -values.drag_total.y;
@ -191,32 +185,36 @@ fn update(
for (value, mut text_span) in watched_values_query.iter_mut() { for (value, mut text_span) in watched_values_query.iter_mut() {
text_span.0 = match value { text_span.0 = match value {
ValueLabel::TargetScaleFactor => target_scale_factor.to_string(), ValueLabel::RenderTargetScaleFactor => {
(computed_target.scale_factor() / ui_scale.0).to_string()
}
ValueLabel::UiScale => ui_scale.0.to_string(), ValueLabel::UiScale => ui_scale.0.to_string(),
ValueLabel::CombinedScaleFactor => (target_scale_factor * ui_scale.0).to_string(), ValueLabel::CombinedScaleFactor => computed_target.scale_factor().to_string(),
ValueLabel::MouseMotionSum => values.mouse_motion_sum.to_string(), ValueLabel::MouseMotionSum => values.mouse_motion_sum.to_string(),
ValueLabel::DragDeltaSum => values.drag_delta_sum.to_string(), ValueLabel::DragDeltaSum => values.drag_delta_sum.to_string(),
ValueLabel::DragDistance => values.drag_distance.to_string(), ValueLabel::DragDistance => values.drag_distance.to_string(),
ValueLabel::PhysicalNodeSize => computed_node_size.to_string(), ValueLabel::PhysicalNodeSize => computed_node.size().to_string(),
ValueLabel::LogicalNodeSize => (computed_node_size / combined_scale_factor).to_string(), ValueLabel::LogicalNodeSize => {
(computed_node.size() / computed_target.scale_factor()).to_string()
}
ValueLabel::DragPointerLocation => format!("{:?}", values.drag_pointer_location), ValueLabel::DragPointerLocation => format!("{:?}", values.drag_pointer_location),
ValueLabel::ScrollPosition => format!("{:?}", current_scroll_position), ValueLabel::ScrollPosition => format!("{:?}", current_scroll_position),
} }
} }
for (_, mut node) in drag_node.iter_mut() { let logical_drag_distance = values.drag_distance / ui_scale.0;
node.width = Val::Px(scaled_distance.x.abs()); let logical_drag_start = values.drag_start / ui_scale.0;
node.height = Val::Px(scaled_distance.y.abs()); node.width = Val::Px(logical_drag_distance.x.abs());
if scaled_distance.x < 0. { node.height = Val::Px(logical_drag_distance.y.abs());
node.left = Val::Px(values.drag_start.x / ui_scale.0 + scaled_distance.x); if logical_drag_distance.x < 0. {
} else { node.left = Val::Px(logical_drag_start.x + logical_drag_distance.x);
node.left = Val::Px(values.drag_start.x / ui_scale.0); } else {
} node.left = Val::Px(logical_drag_start.x);
}
if scaled_distance.y < 0. { if logical_drag_distance.y < 0. {
node.top = Val::Px(values.drag_start.y / ui_scale.0 + scaled_distance.y); node.top = Val::Px(logical_drag_start.y + logical_drag_distance.y);
} else { } else {
node.top = Val::Px(values.drag_start.y / ui_scale.0); node.top = Val::Px(logical_drag_start.y);
}
} }
} }