Skip to content

Commit b8cfac0

Browse files
author
jkukatzki
committed
responsive column widths for rows in inspector
1 parent 7394781 commit b8cfac0

6 files changed

Lines changed: 120 additions & 40 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
11
pub mod delaunay;
22
pub mod geometry;
33
pub mod loading;
4+
5+
use bevy::asset::AssetPath;
6+
use std::path::PathBuf;
7+
8+
/// Normalize an [`AssetPath`] to use forward slashes, ensuring portability across platforms.
9+
///
10+
/// On Windows, `std::path::Path` uses backslashes as separators. This function converts them to
11+
/// forward slashes so that serialized asset paths can be loaded on any platform.
12+
pub fn normalize_asset_path(path: AssetPath<'static>) -> AssetPath<'static> {
13+
let normalized = AssetPath::from_path_buf(PathBuf::from(
14+
path.path().to_string_lossy().replace('\\', "/"),
15+
));
16+
match path.label() {
17+
Some(label) => normalized.with_label(label.to_string()).into_owned(),
18+
None => normalized.into_owned(),
19+
}
20+
}
21+

crates/bevy_animation_graph_editor/src/ui/generic_widgets/graph_input_pin.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ impl<'a> egui::Widget for GraphInputPinWidget<'a> {
4848
GraphInputPin::Passthrough(pin_id)
4949
| GraphInputPin::FromFsmSource(pin_id)
5050
| GraphInputPin::FromFsmTarget(pin_id) => {
51-
response |= ui.add(egui::TextEdit::singleline(pin_id).desired_width(100.));
51+
response |= ui.add(
52+
egui::TextEdit::singleline(pin_id).desired_width(ui.available_width()),
53+
);
5254
}
5355
GraphInputPin::FsmBuiltin(fsm_builtin_pin) => {
5456
let original = fsm_builtin_pin.clone();

crates/bevy_animation_graph_editor/src/ui/generic_widgets/hash_like.rs

Lines changed: 65 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
11
use std::{hash::Hash, marker::PhantomData};
22

3+
/// Creates a child Ui with a fixed width that won't overflow into the parent's
4+
/// horizontal layout, even if the child content is wider than `col_width`.
5+
fn fixed_width_column(
6+
ui: &mut egui::Ui,
7+
id: egui::Id,
8+
col_width: f32,
9+
add_contents: impl FnOnce(&mut egui::Ui) -> egui::Response,
10+
) -> egui::Response {
11+
let col_rect = egui::Rect::from_min_size(
12+
ui.cursor().min,
13+
egui::vec2(col_width, ui.max_rect().bottom() - ui.cursor().min.y),
14+
);
15+
let mut child_ui = ui.new_child(
16+
egui::UiBuilder::new()
17+
.id_salt(id)
18+
.max_rect(col_rect)
19+
.layout(*ui.layout()),
20+
);
21+
let response = add_contents(&mut child_ui);
22+
let used_height = child_ui.min_rect().height();
23+
// Advance parent cursor by exactly col_width, regardless of child overflow
24+
ui.advance_cursor_after_rect(egui::Rect::from_min_size(
25+
col_rect.min,
26+
egui::vec2(col_width, used_height),
27+
));
28+
response
29+
}
30+
331
pub struct HashLikeWidget<'a, K, V, C, H> {
432
pub map: &'a mut H,
533
pub id_hash: egui::Id,
@@ -44,8 +72,8 @@ where
4472
let mut pending_delete_key_idx = None;
4573
let mut pending_add_key = None;
4674

47-
egui::Grid::new(self.id_hash.with("hashmap grid")).show(ui, |ui| {
48-
for (idx, key) in buffer.ordering.iter_mut().enumerate() {
75+
for (idx, key) in buffer.ordering.iter_mut().enumerate() {
76+
ui.horizontal(|ui| {
4977
ui.push_id(egui::Id::new(idx).with("delete button"), |ui| {
5078
let button_response = ui.button("x");
5179
if button_response.clicked() {
@@ -56,23 +84,28 @@ where
5684
response |= button_response;
5785
});
5886

59-
ui.push_id(egui::Id::new(idx).with("edit existing key"), |ui| {
60-
response |= self.map.edit_existing_key(ui, key);
61-
});
62-
63-
ui.push_id(egui::Id::new(idx).with("edit existing value"), |ui| {
64-
response |= self.map.edit_existing_value_for(ui, key);
65-
});
66-
67-
ui.end_row();
68-
}
87+
let spacing = ui.spacing().item_spacing.x;
88+
let col_width = (ui.available_width() - spacing).max(0.) / 2.0;
89+
90+
response |= fixed_width_column(
91+
ui,
92+
egui::Id::new(idx).with("edit existing key"),
93+
col_width,
94+
|ui| self.map.edit_existing_key(ui, key),
95+
);
96+
response |= fixed_width_column(
97+
ui,
98+
egui::Id::new(idx).with("edit existing value"),
99+
col_width,
100+
|ui| self.map.edit_existing_value_for(ui, key),
101+
);
102+
});
103+
}
69104

70-
ui.separator();
71-
ui.separator();
72-
ui.separator();
73-
ui.end_row();
105+
ui.separator();
74106

75-
ui.push_id(egui::Id::new(-1).with("create button"), |ui| {
107+
ui.horizontal(|ui| {
108+
ui.push_id(egui::Id::new(-1i32).with("create button"), |ui| {
76109
let button_response = ui.button("+");
77110
if button_response.clicked() {
78111
pending_add_key = Some(key.clone());
@@ -83,13 +116,21 @@ where
83116
response |= button_response;
84117
});
85118

86-
ui.push_id(egui::Id::new(-1).with("edit new key"), |ui| {
87-
response |= self.map.edit_new_key(ui, key, context);
88-
});
89-
90-
ui.push_id(egui::Id::new(-1).with("edit new value"), |ui| {
91-
response |= self.map.edit_new_value(ui, value, context);
92-
});
119+
let spacing = ui.spacing().item_spacing.x;
120+
let col_width = (ui.available_width() - spacing).max(0.) / 2.0;
121+
122+
response |= fixed_width_column(
123+
ui,
124+
egui::Id::new(-1i32).with("edit new key"),
125+
col_width,
126+
|ui| self.map.edit_new_key(ui, key, context),
127+
);
128+
response |= fixed_width_column(
129+
ui,
130+
egui::Id::new(-1i32).with("edit new value"),
131+
col_width,
132+
|ui| self.map.edit_new_value(ui, value, context),
133+
);
93134
});
94135

95136
if let Some(delete_idx) = pending_delete_key_idx {

crates/bevy_animation_graph_editor/src/ui/generic_widgets/io_spec.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,18 @@ impl<'a, I: Clone + std::fmt::Debug + Eq + std::hash::Hash + Default + Send + Sy
193193
input: &mut I,
194194
spec: &mut DataSpec,
195195
) -> egui::Response {
196-
let mut response = show_i(ui, input);
197-
response |= ui.add(DataSpecWidget::new_salted(spec, "data spec widget"));
198-
196+
let mut response = ui.allocate_response(egui::Vec2::ZERO, egui::Sense::hover());
197+
egui_extras::StripBuilder::new(ui)
198+
.size(egui_extras::Size::remainder())
199+
.size(egui_extras::Size::initial(80.))
200+
.horizontal(|mut strip| {
201+
strip.cell(|ui| {
202+
response |= show_i(ui, input);
203+
});
204+
strip.cell(|ui| {
205+
response |= ui.add(DataSpecWidget::new_salted(spec, "data spec widget"));
206+
});
207+
});
199208
response
200209
}
201210

@@ -296,9 +305,19 @@ impl<'a, I: Clone + std::fmt::Debug + Eq + std::hash::Hash + Default + Send + Sy
296305
input: &mut PinId,
297306
spec: &mut DataSpec,
298307
) -> egui::Response {
299-
let mut response = ui.add(egui::TextEdit::singleline(input).desired_width(100.));
300-
response |= ui.add(DataSpecWidget::new_salted(spec, "data spec widget"));
301-
308+
let mut response = ui.allocate_response(egui::Vec2::ZERO, egui::Sense::hover());
309+
egui_extras::StripBuilder::new(ui)
310+
.size(egui_extras::Size::remainder())
311+
.size(egui_extras::Size::initial(80.))
312+
.horizontal(|mut strip| {
313+
strip.cell(|ui| {
314+
response |=
315+
ui.add(egui::TextEdit::singleline(input).desired_width(f32::INFINITY));
316+
});
317+
strip.cell(|ui| {
318+
response |= ui.add(DataSpecWidget::new_salted(spec, "data spec widget"));
319+
});
320+
});
302321
response
303322
}
304323

crates/bevy_animation_graph_editor/src/ui/generic_widgets/vec2.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,24 @@ impl<'a> Vec2Widget<'a> {
3333
impl<'a> egui::Widget for Vec2Widget<'a> {
3434
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
3535
ui.push_id(self.id_hash, |ui| {
36-
let mut total_size = ui.available_size();
37-
total_size.x = self.width;
36+
let slot_height = ui.spacing().interact_size.y;
37+
let slot_width = ui.available_width().min(self.width);
3838
ui.horizontal(|ui| {
3939
let x_id = ui.id().with(self.id_hash).with("vec3 x");
4040
let y_id = ui.id().with(self.id_hash).with("vec3 y");
4141

4242
let x_response = ui
4343
.push_id(x_id, |ui| {
4444
ui.add_sized(
45-
egui::Vec2::new(total_size.x / 3.1, total_size.y),
45+
egui::Vec2::new(slot_width / 3.1, slot_height),
4646
egui::DragValue::new(&mut self.vec2.x).speed(self.slider_step_size),
4747
)
4848
})
4949
.inner;
5050
let y_response = ui
5151
.push_id(y_id, |ui| {
5252
ui.add_sized(
53-
egui::Vec2::new(total_size.x / 3.1, total_size.y),
53+
egui::Vec2::new(slot_width / 3.1, slot_height),
5454
egui::DragValue::new(&mut self.vec2.y).speed(self.slider_step_size),
5555
)
5656
})

crates/bevy_animation_graph_editor/src/ui/generic_widgets/vec3.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ impl<'a> Vec3Widget<'a> {
3131
impl<'a> egui::Widget for Vec3Widget<'a> {
3232
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
3333
ui.push_id(self.id_hash, |ui| {
34-
let mut total_size = ui.available_size();
35-
total_size.x = self.width;
34+
let slot_height = ui.spacing().interact_size.y;
35+
let slot_width = ui.available_width().min(self.width);
3636
ui.horizontal(|ui| {
3737
let x_id = ui.id().with(self.id_hash).with("vec3 x");
3838
let y_id = ui.id().with(self.id_hash).with("vec3 y");
@@ -41,23 +41,23 @@ impl<'a> egui::Widget for Vec3Widget<'a> {
4141
let x_response = ui
4242
.push_id(x_id, |ui| {
4343
ui.add_sized(
44-
egui::Vec2::new(total_size.x / 3.1, total_size.y),
44+
egui::Vec2::new(slot_width / 3.1, slot_height),
4545
egui::DragValue::new(&mut self.vec3.x).speed(self.slider_step_size),
4646
)
4747
})
4848
.inner;
4949
let y_response = ui
5050
.push_id(y_id, |ui| {
5151
ui.add_sized(
52-
egui::Vec2::new(total_size.x / 3.1, total_size.y),
52+
egui::Vec2::new(slot_width / 3.1, slot_height),
5353
egui::DragValue::new(&mut self.vec3.y).speed(self.slider_step_size),
5454
)
5555
})
5656
.inner;
5757
let z_response = ui
5858
.push_id(z_id, |ui| {
5959
ui.add_sized(
60-
egui::Vec2::new(total_size.x / 3.1, total_size.y),
60+
egui::Vec2::new(slot_width / 3.1, slot_height),
6161
egui::DragValue::new(&mut self.vec3.z).speed(self.slider_step_size),
6262
)
6363
})

0 commit comments

Comments
 (0)