diff --git a/src/editor_project.rs b/src/editor_project.rs index 0ca4cc3..e0bd9a2 100644 --- a/src/editor_project.rs +++ b/src/editor_project.rs @@ -24,6 +24,9 @@ pub struct EditorProject { pub mask_size: u16, soft_key_size: (u16, u16), object_info: RefCell>, + + /// Used to keep track of the object that is being renamed + renaming_object: RefCell>, } impl From for EditorProject { @@ -41,6 +44,7 @@ impl From for EditorProject { mask_size, soft_key_size, object_info: RefCell::new(HashMap::new()), + renaming_object: RefCell::new(None), } } } @@ -167,13 +171,35 @@ impl EditorProject { /// Get the object info for an object id /// If the object id is not mapped, we insert the default object info pub fn get_object_info(&self, object: &Object) -> ObjectInfo { - if let Some(info) = self.object_info.borrow().get(&object.id()) { - return info.clone(); + let mut object_info = self.object_info.borrow_mut(); + object_info + .entry(object.id()) + .or_insert_with(|| ObjectInfo::new(object)) + .clone() + } + + /// Start renaming an object + pub fn set_renaming_object(&self, ui_id: eframe::egui::Id, object_id: ObjectId, name: String) { + self.renaming_object.replace(Some((ui_id, object_id, name))); + } + + /// Get the current name of the object that is being renamed + /// Returns None if no object is being renamed + pub fn get_renaming_object(&self) -> Option<(eframe::egui::Id, ObjectId, String)> { + self.renaming_object.borrow().clone() + } + + /// Finish renaming an object + /// If store is true, we store the new name in the object info hashmap + pub fn finish_renaming_object(&self, store: bool) { + if store { + if let Some(renaming_object) = self.renaming_object.borrow().as_ref() { + let mut object_info = self.object_info.borrow_mut(); + if let Some(info) = object_info.get_mut(&renaming_object.1) { + info.set_name(renaming_object.2.clone()); + } + } } - let info = ObjectInfo::new(object); - self.object_info - .borrow_mut() - .insert(object.id(), info.clone()); - info + self.renaming_object.replace(None); } } diff --git a/src/main.rs b/src/main.rs index 4562da6..4211858 100644 --- a/src/main.rs +++ b/src/main.rs @@ -192,20 +192,48 @@ impl<'a> egui::Widget for ObjectWrapper<'a> { } fn render_selectable_object(ui: &mut egui::Ui, object: &Object, project: &EditorProject) { - let name = project.get_object_info(object).get_name(object); - let is_selected = project.get_selected() == object.id().into(); - let response = ui.selectable_label(is_selected, name); - - if response.clicked() { - project - .get_mut_selected() - .replace(NullableObjectId(Some(object.id()))); - } - response.context_menu(|ui| { - if ui.button("Delete").on_hover_text("Delete object").clicked() { - project.get_mut_pool().borrow_mut().remove(object.id()); + let this_ui_id = ui.id(); + let object_info = project.get_object_info(object); + + let renaming_object = project.get_renaming_object(); + if renaming_object + .clone() + .is_some_and(|(ui_id, id, _)| id == object.id() && ui_id == this_ui_id) + { + let mut name = renaming_object.unwrap().2; + let response = ui.text_edit_singleline(&mut name); + project.set_renaming_object(this_ui_id, object.id(), name); // Update the name in the project + let cancelled = ui.input(|i| i.key_pressed(egui::Key::Escape)); + if response.lost_focus() { + project.finish_renaming_object(!cancelled); + } else if !response.has_focus() { + // We need to focus the text edit when we start renaming + response.request_focus(); } - }); + } else { + let is_selected = project.get_selected() == object.id().into(); + let response = ui.selectable_label(is_selected, object_info.get_name(object)); + + if response.clicked() { + project + .get_mut_selected() + .replace(NullableObjectId(Some(object.id()))); + } + if response.double_clicked() { + project.set_renaming_object(this_ui_id, object.id(), object_info.get_name(object)); + } + + response.context_menu(|ui| { + if ui.button("Rename").on_hover_text("Rename object").clicked() { + project.set_renaming_object(this_ui_id, object.id(), object_info.get_name(object)); + ui.close_menu(); + } + if ui.button("Delete").on_hover_text("Delete object").clicked() { + project.get_mut_pool().borrow_mut().remove(object.id()); + ui.close_menu(); + } + }); + } } fn render_object_hierarchy( diff --git a/src/object_info.rs b/src/object_info.rs index 7621d52..752d758 100644 --- a/src/object_info.rs +++ b/src/object_info.rs @@ -35,6 +35,11 @@ impl ObjectInfo { } } + /// Set the name of the object. + pub fn set_name(&mut self, name: String) { + self.name = Some(name); + } + pub fn get_unique_id(&self) -> Uuid { self.unique_id }