Skip to content

Commit b02b97b

Browse files
committed
Redesign asset browser: compact grid, inline create/rename, improved context menu
1 parent d3882ea commit b02b97b

6 files changed

Lines changed: 306 additions & 282 deletions

File tree

crates/editor/renzora_asset_browser/src/grid.rs

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -172,16 +172,18 @@ pub fn grid_ui_interactive(
172172
let mut drag_started_index: Option<usize> = None;
173173
let mut thumbnail_requests: Vec<PathBuf> = Vec::new();
174174
let mut right_clicked = false;
175+
let mut pending_rename_rect: Option<egui::Rect> = None;
176+
let mut pending_rename_font: f32 = 11.0;
175177

176178
// The visible grid pane rect (used for hit-testing pointer vs grid area)
177179
let grid_pane_rect = ui.max_rect();
178180

179181
egui::ScrollArea::vertical()
180182
.id_salt("asset_grid")
181183
.auto_shrink([false, false])
184+
.drag_to_scroll(false)
182185
.show(ui, |ui| {
183-
ui.add_space(4.0);
184-
186+
ui.add_space(5.0);
185187
let grid = TileGrid::new(theme)
186188
.zoom(zoom)
187189
.available_width(ui.available_width());
@@ -228,33 +230,9 @@ pub fn grid_ui_interactive(
228230
// Inline rename UI
229231
let is_renaming = state.renaming_asset.as_ref() == Some(&entry.path);
230232
if is_renaming {
231-
// Draw rename TextEdit in the label area
232-
let rename_rect = tile.label_rect;
233-
let rename_id = ui.id().with("rename_input");
234-
let mut text = state.rename_buffer.clone();
235-
let resp = ui.put(
236-
rename_rect,
237-
egui::TextEdit::singleline(&mut text)
238-
.font(FontId::proportional(tile.font_size))
239-
.desired_width(rename_rect.width())
240-
.id(rename_id),
241-
);
242-
state.rename_buffer = text;
243-
244-
if !state.rename_focus_set {
245-
resp.request_focus();
246-
state.rename_focus_set = true;
247-
}
248-
249-
// Enter to confirm rename
250-
if resp.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
251-
let new_name = state.rename_buffer.trim().to_string();
252-
if !new_name.is_empty() && new_name != entry.name {
253-
state.pending_rename = Some((entry.path.clone(), new_name));
254-
}
255-
state.renaming_asset = None;
256-
}
257-
// Escape handled above
233+
// Stash rename info to render outside the grid layout
234+
pending_rename_rect = Some(tile.label_rect);
235+
pending_rename_font = tile.font_size;
258236
}
259237

260238
// Try to render an image thumbnail for supported file types
@@ -330,6 +308,46 @@ pub fn grid_ui_interactive(
330308
}
331309
}
332310

311+
// --- Inline rename (rendered outside grid layout to avoid breaking flow) ---
312+
if let Some(rename_rect) = pending_rename_rect {
313+
let rename_id = egui::Id::new("asset_grid_rename_input");
314+
let mut text = state.rename_buffer.clone();
315+
let area_resp = egui::Area::new(rename_id.with("area"))
316+
.fixed_pos(rename_rect.min)
317+
.order(egui::Order::Foreground)
318+
.show(&ctx, |ui| {
319+
ui.set_max_width(rename_rect.width());
320+
ui.add(
321+
egui::TextEdit::singleline(&mut text)
322+
.font(FontId::proportional(pending_rename_font))
323+
.desired_width(rename_rect.width() - 8.0)
324+
.id(rename_id),
325+
)
326+
});
327+
let resp = area_resp.inner;
328+
state.rename_buffer = text;
329+
330+
if !state.rename_focus_set {
331+
resp.request_focus();
332+
state.rename_focus_set = true;
333+
}
334+
335+
if resp.lost_focus() {
336+
if ctx.input(|i| i.key_pressed(egui::Key::Enter)) {
337+
// Confirm rename
338+
let new_name = state.rename_buffer.trim().to_string();
339+
if let Some(ref renaming) = state.renaming_asset {
340+
let old_name = renaming.file_name().and_then(|n| n.to_str()).unwrap_or("");
341+
if !new_name.is_empty() && new_name != old_name {
342+
state.pending_rename = Some((renaming.clone(), new_name));
343+
}
344+
}
345+
}
346+
// Cancel on click-away or Escape — discard changes
347+
state.renaming_asset = None;
348+
}
349+
}
350+
333351
if right_clicked {
334352
state.context_menu_pos = ctx.pointer_latest_pos();
335353
}

0 commit comments

Comments
 (0)