reparenting fixes to avoid deleting elements accidentally

This commit is contained in:
adia redmoon 2024-04-25 05:50:01 -07:00
parent 18a93e44df
commit e2b9aa3313
2 changed files with 86 additions and 6 deletions

View file

@ -535,7 +535,9 @@ pub fn show_popup(state: &mut EditWindowUIState, contexts: &mut EguiContexts) {
ui.collapsing("Reparent to child of", |ui| {
ui.vertical(|ui| {
for each in state.structure.list_of_elements() {
if each != cur && Some(&each) != state.structure.parent_of(&cur.clone())
if each != cur
&& Some(&each) != state.structure.parent_of(&cur.clone())
&& !state.structure.is_upstream_of(&cur, &each)
{
if ui.button(&each).clicked() {
reparent = Some((cur.clone(), each));
@ -543,6 +545,12 @@ pub fn show_popup(state: &mut EditWindowUIState, contexts: &mut EguiContexts) {
}
}
}
if state.structure.parent_of(&cur).is_some() {
if ui.button("None").clicked() {
reparent = Some((cur.clone(), "".into()));
change_state = Some(PopupWindowData::None);
}
}
});
});
// todo: rename action. edit subject action (mesh, light), remove action (with, without reparenting)
@ -556,21 +564,27 @@ pub fn show_popup(state: &mut EditWindowUIState, contexts: &mut EguiContexts) {
state.popup = change_state.unwrap();
}
if let Some((cur, next)) = reparent {
state.structure.move_branch(&cur, &next);
if next != "" {
state.structure.move_branch(&cur, &next);
} else {
state.structure.deparent(&cur);
}
}
}
pub fn show_editable_stringtree(ui: &mut egui::Ui, state: &mut EditWindowUIState) {
ui.collapsing("Model Structure", |ui| {
ui.vertical(|ui| {
for each in &mut state.structure.root {
for each in &state.structure.root {
match each {
super::ui_extensions::StringTreeElement::None => {}
super::ui_extensions::StringTreeElement::Element(name, children) => {
ui.horizontal(|ui| {
ui.label(">".to_owned());
if ui.button(name.clone()).clicked() {
//
ui.label(name.clone());
let but = egui::Button::new("...");
if ui.add_enabled(true, but).clicked() {
let mut should_close = false;
if let PopupWindowData::StructureElement(val) = &state.popup {
if val == name {
@ -613,7 +627,8 @@ pub fn show_child(
prec = prec + ">";
ui.horizontal(|ui| {
ui.label(prec);
if ui.button(name.clone()).clicked() {
ui.label(name.clone());
if ui.button("...").clicked() {
let mut should_close = false;
if let PopupWindowData::StructureElement(val) = state {
if val == name {
@ -677,3 +692,13 @@ pub fn round_trip_color() {
assert_eq!((color.b() * 255.).floor(), (b * 255.).floor());
}
}
#[test]
pub fn test_string_refref() {
let string = "test".to_owned();
let string2 = "test2".to_owned();
let mut reference = &string;
let refref: &mut &String = &mut reference;
*refref = &string2;
assert_eq!(*refref, &string2);
}

View file

@ -20,6 +20,23 @@ impl StringTreeElement {
pub fn new(key: &String) -> StringTreeElement {
StringTreeElement::Element(key.clone(), Box::new(Vec::new()))
}
pub fn contains_down_branch(&self, search: &String) -> bool {
self.down_branch(search)
}
fn down_branch(&self, search: &String) -> bool {
if let StringTreeElement::Element(name, children) = &self {
if name == search {
return true;
} else {
for each in children.as_ref() {
if each.down_branch(search) {
return true;
}
}
}
}
false
}
}
#[derive(Default, Debug, Clone)]
pub struct StringTree {
@ -69,6 +86,10 @@ impl StringTree {
false
}
pub fn is_present(&self, key: &String) -> bool {
// will not allow empty strings
if key == "" {
return true;
}
for each in &self.root {
let res = Self::check_present(each, key);
if res {
@ -264,6 +285,40 @@ impl StringTree {
false
} */
pub fn deparent(&mut self, subject: &String) -> bool {
let x = self.pop_branch(subject);
if x.is_some() {
self.root.push(x.unwrap());
return true;
}
false
}
pub fn is_upstream_of(&self, parent: &String, child: &String) -> bool {
let mut subject: Option<&String> = self.parent_of(child);
while subject.is_some() {
if let Some(val) = subject {
if val == parent {
return true;
}
}
subject = self.parent_of(subject.unwrap());
}
false
}
pub fn could_be_moved(&self, name: &String) -> bool {
let list = self.list_of_elements();
for each in list {
if !self.is_upstream_of(&each, name) {
if !self.is_upstream_of(name, &each) {
if &each != name {
return true;
}
}
}
}
false
}
pub fn list_of_elements(&self) -> Vec<String> {
let mut list: Vec<String> = Vec::new();
let mut to_search = Vec::new();