Преглед изворни кода

app/prop: add get/set_X_vec() methods to Property, and make use of this for menu cancel action (to reset menu to prev state).

darkfi пре 5 месеци
родитељ
комит
f87fd7a6f4
2 измењених фајлова са 136 додато и 22 уклоњено
  1. 134 3
      bin/app/src/prop/mod.rs
  2. 2 19
      bin/app/src/ui/menu/mod.rs

+ 134 - 3
bin/app/src/prop/mod.rs

@@ -199,6 +199,7 @@ impl Encodable for PropertyValue {
 pub enum ModifyAction {
     Clear,
     Set(usize),
+    SetVec,
     SetCache(Vec<usize>),
     Push(usize),
     Insert(usize),
@@ -544,16 +545,85 @@ impl Property {
         Ok(())
     }
 
+    fn set_value_vec<T, F>(
+        self: &Arc<Self>,
+        atom: &mut PropertyAtomicGuard,
+        role: Role,
+        val: Vec<T>,
+        f: F,
+    ) -> Result<()>
+    where
+        F: Fn(T) -> PropertyValue,
+    {
+        if self.is_bounded() {
+            return Err(Error::PropertyIsBounded)
+        }
+
+        {
+            let mut vals = self.vals.lock().unwrap();
+            vals.clear();
+            vals.extend(val.into_iter().map(f));
+        }
+
+        atom.add(self.clone(), role, ModifyAction::SetVec);
+        Ok(())
+    }
+
+    pub fn set_bool_vec(
+        self: &Arc<Self>,
+        atom: &mut PropertyAtomicGuard,
+        role: Role,
+        val: Vec<bool>,
+    ) -> Result<()> {
+        self.set_value_vec(atom, role, val, PropertyValue::Bool)
+    }
+
+    pub fn set_u32_vec(
+        self: &Arc<Self>,
+        atom: &mut PropertyAtomicGuard,
+        role: Role,
+        val: Vec<u32>,
+    ) -> Result<()> {
+        self.set_value_vec(atom, role, val, PropertyValue::Uint32)
+    }
+
     pub fn set_f32_vec(
         self: &Arc<Self>,
         atom: &mut PropertyAtomicGuard,
         role: Role,
         val: Vec<f32>,
     ) -> Result<()> {
-        for (i, &val) in val.iter().enumerate() {
-            self.clone().set_f32(atom, role, i, val)?;
+        self.set_value_vec(atom, role, val, PropertyValue::Float32)
+    }
+
+    pub fn set_str_vec<S: Into<String>>(
+        self: &Arc<Self>,
+        atom: &mut PropertyAtomicGuard,
+        role: Role,
+        val: Vec<S>,
+    ) -> Result<()> {
+        self.set_value_vec(atom, role, val, |v| PropertyValue::Str(v.into()))
+    }
+
+    pub fn set_enum_vec<S: Into<String>>(
+        self: &Arc<Self>,
+        atom: &mut PropertyAtomicGuard,
+        role: Role,
+        val: Vec<S>,
+    ) -> Result<()> {
+        if self.typ != PropertyType::Enum {
+            return Err(Error::PropertyWrongType)
         }
-        Ok(())
+        self.set_value_vec(atom, role, val, |v| PropertyValue::Enum(v.into()))
+    }
+
+    pub fn set_node_id_vec(
+        self: &Arc<Self>,
+        atom: &mut PropertyAtomicGuard,
+        role: Role,
+        val: Vec<SceneNodeId>,
+    ) -> Result<()> {
+        self.set_value_vec(atom, role, val, PropertyValue::SceneNodeId)
     }
 
     fn set_cache(&self, i: usize, val: PropertyValue) -> Result<()> {
@@ -1035,6 +1105,67 @@ impl Property {
         Ok(cache[i].clone())
     }
 
+    fn get_value_vec<T, F>(&self, f: F) -> Result<Vec<T>>
+    where
+        F: Fn(&PropertyValue) -> Option<T>,
+    {
+        if self.is_bounded() {
+            return Err(Error::PropertyIsBounded)
+        }
+
+        let vals = self.vals.lock().unwrap();
+        let mut result = Vec::with_capacity(vals.len());
+        for val in vals.iter() {
+            match f(val) {
+                Some(v) => result.push(v),
+                None => return Err(Error::PropertyWrongType),
+            }
+        }
+        Ok(result)
+    }
+
+    pub fn get_bool_vec(&self) -> Result<Vec<bool>> {
+        self.get_value_vec(|val| match val {
+            PropertyValue::Bool(v) => Some(*v),
+            _ => None,
+        })
+    }
+
+    pub fn get_u32_vec(&self) -> Result<Vec<u32>> {
+        self.get_value_vec(|val| match val {
+            PropertyValue::Uint32(v) => Some(*v),
+            _ => None,
+        })
+    }
+
+    pub fn get_f32_vec(&self) -> Result<Vec<f32>> {
+        self.get_value_vec(|val| match val {
+            PropertyValue::Float32(v) => Some(*v),
+            _ => None,
+        })
+    }
+
+    pub fn get_str_vec(&self) -> Result<Vec<String>> {
+        self.get_value_vec(|val| match val {
+            PropertyValue::Str(v) => Some(v.clone()),
+            _ => None,
+        })
+    }
+
+    pub fn get_enum_vec(&self) -> Result<Vec<String>> {
+        self.get_value_vec(|val| match val {
+            PropertyValue::Enum(v) => Some(v.clone()),
+            _ => None,
+        })
+    }
+
+    pub fn get_node_id_vec(&self) -> Result<Vec<SceneNodeId>> {
+        self.get_value_vec(|val| match val {
+            PropertyValue::SceneNodeId(v) => Some(*v),
+            _ => None,
+        })
+    }
+
     // Subs
 
     pub fn subscribe_modify(&self) -> Subscription<(Role, ModifyAction, BatchGuardPtr)> {

+ 2 - 19
bin/app/src/ui/menu/mod.rs

@@ -239,13 +239,8 @@ impl Menu {
 
     /// Save the current menu items layout
     fn save_items_layout(&self) {
-        let num_items = self.items.get_len();
-        let mut items = Vec::with_capacity(num_items);
-        for idx in 0..num_items {
-            items.push(self.items.get_str(idx).unwrap());
-        }
+        let items = self.items.get_str_vec().unwrap();
         *self.saved_items.lock() = Some(items);
-        d!("Saved menu layout with {} items", num_items);
     }
 
     /// Height of the content without the overscroll
@@ -647,19 +642,7 @@ impl Menu {
         let saved = self_.saved_items.lock().take();
         if let Some(items) = saved {
             let atom = &mut self_.renderer.make_guard(gfxtag!("Menu::cancel_edit"));
-
-            // Clear current items
-            let current_len = self_.items.get_len();
-            for _ in 0..current_len {
-                self_.items.remove_str(atom, Role::App, 0).unwrap();
-            }
-
-            // Restore saved items
-            for (idx, item) in items.iter().enumerate() {
-                self_.items.insert_str(atom, Role::App, idx, item).unwrap();
-            }
-
-            d!("cancel: restored {} items", items.len());
+            self_.items.set_str_vec(atom, Role::App, items).unwrap();
         }
 
         // Exit edit mode