stringtree and test for it
This commit is contained in:
parent
cbe54774b8
commit
40d7d8f949
|
@ -7,6 +7,7 @@ use crate::vvlib::oct_asset::{self, OctAssetMarker, OctTreeAsset};
|
|||
mod editor_bevy_input_shim;
|
||||
pub mod editor_ui;
|
||||
mod orbit_camera;
|
||||
pub mod ui_extensions;
|
||||
|
||||
pub fn setup(app: &mut App) -> &mut App {
|
||||
app.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||
|
|
|
@ -193,10 +193,3 @@ pub fn round_trip_color() {
|
|||
assert_eq!((color.b() * 255.).floor(), (b * 255.).floor());
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
pub fn test_colors() {
|
||||
let color = Color::rgb(1., 0., 0.);
|
||||
//let x = Hsva::from_srgb()
|
||||
let hsv = egui_color_from(color);
|
||||
let conv = rgb_from_hsv((hsv.h, hsv.s, hsv.v));
|
||||
}
|
||||
|
|
287
src/vvedit/ui_extensions.rs
Normal file
287
src/vvedit/ui_extensions.rs
Normal file
|
@ -0,0 +1,287 @@
|
|||
#[derive(Default, Debug, Clone)]
|
||||
pub enum StringTreeElement {
|
||||
#[default]
|
||||
None,
|
||||
Element(String, Box<Vec<StringTreeElement>>),
|
||||
}
|
||||
impl StringTreeElement {
|
||||
pub fn is_none(&self) -> bool {
|
||||
match self {
|
||||
StringTreeElement::None => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn name_of(&self) -> Option<&String> {
|
||||
match self {
|
||||
StringTreeElement::Element(name, _) => Some(name),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
pub fn new(key: &String) -> StringTreeElement {
|
||||
StringTreeElement::Element(key.clone(), Box::new(Vec::new()))
|
||||
}
|
||||
}
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct StringTree {
|
||||
root: Vec<StringTreeElement>,
|
||||
}
|
||||
impl StringTree {
|
||||
pub fn new() -> Self {
|
||||
StringTree { root: Vec::new() }
|
||||
}
|
||||
pub fn add_root_level(&mut self, element: &String) -> bool {
|
||||
for each in &self.root {
|
||||
if Self::check_present(each, element) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
self.root.push(StringTreeElement::new(element));
|
||||
true
|
||||
}
|
||||
pub fn add_child(&mut self, child: &String, parent: &String) -> bool {
|
||||
if !self.is_present(child) {
|
||||
for each in &mut self.root {
|
||||
let res = Self::add_child_to_parent(each, child, parent);
|
||||
if res {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// returns false if parent not found or string already present
|
||||
false
|
||||
}
|
||||
fn add_child_to_parent(
|
||||
element: &mut StringTreeElement,
|
||||
child: &String,
|
||||
parent: &String,
|
||||
) -> bool {
|
||||
if let StringTreeElement::Element(name, children) = element {
|
||||
if name == parent {
|
||||
children.as_mut().push(StringTreeElement::new(child));
|
||||
return true;
|
||||
}
|
||||
for each in children.as_mut() {
|
||||
if Self::add_child_to_parent(each, child, parent) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
pub fn is_present(&self, key: &String) -> bool {
|
||||
for each in &self.root {
|
||||
let res = Self::check_present(each, key);
|
||||
if res {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
fn check_present(element: &StringTreeElement, key: &String) -> bool {
|
||||
if let StringTreeElement::Element(name, children) = element {
|
||||
if name.eq(key) {
|
||||
return true;
|
||||
}
|
||||
for each in children.as_ref() {
|
||||
if Self::check_present(each, key) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
pub fn add(&mut self, element: &String, parent: Option<&String>) -> bool {
|
||||
if let Some(parent) = parent {
|
||||
return self.add_child(element, parent);
|
||||
} else {
|
||||
return self.add_root_level(element);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_branch(&mut self, element: &String, parent: &String) -> bool {
|
||||
if self.is_present(parent) {
|
||||
if let Some(popped) = self.pop_branch(element) {
|
||||
for each in &mut self.root {
|
||||
if Self::place_branch(each, parent, &popped) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
fn place_branch(
|
||||
subject: &mut StringTreeElement,
|
||||
target_parent: &String,
|
||||
element: &StringTreeElement,
|
||||
) -> bool {
|
||||
match subject {
|
||||
StringTreeElement::Element(name, branch) => {
|
||||
//
|
||||
if name == target_parent {
|
||||
branch.push(element.clone());
|
||||
return true;
|
||||
}
|
||||
for each in branch.as_mut() {
|
||||
if Self::place_branch(each, target_parent, element) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn pop_branch(&mut self, element: &String) -> Option<StringTreeElement> {
|
||||
let mut index = usize::MAX;
|
||||
for (ind, each) in (&self.root).iter().enumerate() {
|
||||
if let Some(el) = each.name_of() {
|
||||
if el == element {
|
||||
index = ind;
|
||||
}
|
||||
}
|
||||
}
|
||||
if index != usize::MAX {
|
||||
let popped = self.root.remove(index);
|
||||
return Some(popped);
|
||||
} else {
|
||||
for each in &mut self.root {
|
||||
let x = Self::recursive_branch_find_pop(each, element);
|
||||
if x.is_some() {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
fn recursive_branch_find_pop(
|
||||
iterator: &mut StringTreeElement,
|
||||
name: &String,
|
||||
) -> Option<StringTreeElement> {
|
||||
// name checked in previous iteration
|
||||
if let StringTreeElement::Element(_, branch) = iterator {
|
||||
let mut index = usize::MAX;
|
||||
for each in branch.as_ref().iter().enumerate() {
|
||||
if let Some(el_name) = each.1.name_of() {
|
||||
if el_name == name {
|
||||
index = each.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if index != usize::MAX {
|
||||
let popped = branch.remove(index);
|
||||
return Some(popped);
|
||||
} else {
|
||||
for each in branch.as_mut() {
|
||||
let x = Self::recursive_branch_find_pop(each, name);
|
||||
if x.is_some() {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn remove_branch(&mut self, element: &String) -> bool {
|
||||
return self.pop_branch(element).is_some();
|
||||
}
|
||||
|
||||
pub fn remove_element_preserve_branch(&mut self, search: &String) -> bool {
|
||||
let mut failed_yet = false;
|
||||
let clone = self.clone();
|
||||
let parent = clone.parent_of(search);
|
||||
if let Some(popped) = self.pop_branch(search) {
|
||||
let mut popped = popped;
|
||||
if parent.is_some() {
|
||||
let parent = parent.unwrap();
|
||||
match &mut popped {
|
||||
StringTreeElement::None => {}
|
||||
StringTreeElement::Element(_, branch) => {
|
||||
for each in branch.as_mut() {
|
||||
for branches in &mut self.root {
|
||||
let x = Self::place_branch(branches, parent, &each);
|
||||
if !x {
|
||||
failed_yet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match &mut popped {
|
||||
StringTreeElement::None => {}
|
||||
StringTreeElement::Element(_, branch) => {
|
||||
for each in branch.as_ref() {
|
||||
self.root.push(each.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
!failed_yet
|
||||
}
|
||||
pub fn parent_of(&self, search: &String) -> Option<&String> {
|
||||
let mut queue = Vec::new();
|
||||
|
||||
for each in &self.root {
|
||||
queue.push(each);
|
||||
}
|
||||
while !queue.is_empty() {
|
||||
let element = queue.pop().unwrap();
|
||||
if let StringTreeElement::Element(name, branch) = element {
|
||||
for each in branch.as_ref() {
|
||||
if let Some(c_name) = each.name_of() {
|
||||
if c_name == search {
|
||||
return Some(name);
|
||||
}
|
||||
}
|
||||
queue.push(each);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
/* iterative variation of is_present
|
||||
pub fn contains(&self, search: &String) -> bool {
|
||||
let mut queue = Vec::new();
|
||||
|
||||
for each in &self.root {
|
||||
queue.push(each);
|
||||
}
|
||||
while !queue.is_empty() {
|
||||
let element = queue.pop().unwrap();
|
||||
if let StringTreeElement::Element(name, branch) = element {
|
||||
if name == search {
|
||||
return true;
|
||||
}
|
||||
for each in branch.as_ref() {
|
||||
queue.push(each);
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
} */
|
||||
}
|
||||
#[test]
|
||||
pub fn test_string_tree() {
|
||||
let parent = &String::from("parent1");
|
||||
let parent2 = &String::from("parent2");
|
||||
let child = &String::from("child1");
|
||||
let child2 = &String::from("child2");
|
||||
let mut tester = StringTree::new();
|
||||
tester = dbg!(tester);
|
||||
assert!(dbg!(tester.add(parent, None)));
|
||||
tester = dbg!(tester);
|
||||
assert!(dbg!(tester.add_child(child, parent)));
|
||||
tester = dbg!(tester);
|
||||
assert!(dbg!(tester.add_root_level(parent2)));
|
||||
tester = dbg!(tester);
|
||||
assert!(!dbg!(tester.add_child(child, parent2)));
|
||||
tester = dbg!(tester);
|
||||
assert!(dbg!(tester.add(child2, Some(parent2))));
|
||||
tester = dbg!(tester);
|
||||
assert!(dbg!(tester.move_branch(parent2, parent)));
|
||||
tester = dbg!(tester);
|
||||
}
|
Loading…
Reference in a new issue