Browse Source

app/menu: highlight channel name colors for active msgs and nick mention

jkds 2 weeks ago
parent
commit
b3b3cec459

+ 16 - 12
bin/app/src/app/node.rs

@@ -725,17 +725,17 @@ pub fn create_menu(name: &str) -> SceneNode {
     prop.set_range_f32(0., 1.);
     prop.set_range_f32(0., 1.);
     node.add_property(prop).unwrap();
     node.add_property(prop).unwrap();
 
 
-    let mut prop = Property::new("active_color", PropertyType::Float32, PropertySubType::Color);
-    prop.set_ui_text("Active Color", "Active item text color");
+    let mut prop = Property::new("role1_color", PropertyType::Float32, PropertySubType::Color);
+    prop.set_ui_text("Role1 Color", "Text color for items in role1 group");
     prop.set_array_len(4);
     prop.set_array_len(4);
-    prop.set_defaults_f32(vec![1., 1., 1., 1.]).unwrap();
+    prop.set_defaults_f32(vec![0.36, 1., 0.51, 1.]).unwrap();
     prop.set_range_f32(0., 1.);
     prop.set_range_f32(0., 1.);
     node.add_property(prop).unwrap();
     node.add_property(prop).unwrap();
 
 
-    let mut prop = Property::new("alert_color", PropertyType::Float32, PropertySubType::Color);
-    prop.set_ui_text("Alert Color", "Alert item text color");
+    let mut prop = Property::new("role2_color", PropertyType::Float32, PropertySubType::Color);
+    prop.set_ui_text("Role2 Color", "Text color for items in role2 group");
     prop.set_array_len(4);
     prop.set_array_len(4);
-    prop.set_defaults_f32(vec![1., 0.3, 0.3, 1.]).unwrap();
+    prop.set_defaults_f32(vec![0.56, 0.61, 1., 1.]).unwrap();
     prop.set_range_f32(0., 1.);
     prop.set_range_f32(0., 1.);
     node.add_property(prop).unwrap();
     node.add_property(prop).unwrap();
 
 
@@ -761,6 +761,16 @@ pub fn create_menu(name: &str) -> SceneNode {
     prop.set_unbounded();
     prop.set_unbounded();
     node.add_property(prop).unwrap();
     node.add_property(prop).unwrap();
 
 
+    let mut prop = Property::new("role1_group", PropertyType::Str, PropertySubType::Null);
+    prop.set_ui_text("Role1 Group", "Items colored with role1 color");
+    prop.set_unbounded();
+    node.add_property(prop).unwrap();
+
+    let mut prop = Property::new("role2_group", PropertyType::Str, PropertySubType::Null);
+    prop.set_ui_text("Role2 Group", "Items colored with role2 color");
+    prop.set_unbounded();
+    node.add_property(prop).unwrap();
+
     node.add_signal(
     node.add_signal(
         "select",
         "select",
         "Item selected",
         "Item selected",
@@ -777,12 +787,6 @@ pub fn create_menu(name: &str) -> SceneNode {
     )
     )
     .unwrap();
     .unwrap();
 
 
-    node.add_method("mark_active", vec![("item_name", "Item name", CallArgType::Str)], None)
-        .unwrap();
-
-    node.add_method("mark_alert", vec![("item_name", "Item name", CallArgType::Str)], None)
-        .unwrap();
-
     node.add_method("cancel_edit", vec![], None).unwrap();
     node.add_method("cancel_edit", vec![], None).unwrap();
 
 
     node.add_method("done_edit", vec![], None).unwrap();
     node.add_method("done_edit", vec![], None).unwrap();

+ 0 - 12
bin/app/src/app/schema/menu/channel.rs

@@ -1281,18 +1281,6 @@ pub async fn make(
     prop.set_f32(atom, Role::App, 2, 1.).unwrap();
     prop.set_f32(atom, Role::App, 2, 1.).unwrap();
     prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     prop.set_f32(atom, Role::App, 3, 1.).unwrap();
 
 
-    let prop = node.get_property("active_color").unwrap();
-    prop.set_f32(atom, Role::App, 0, 0.36).unwrap();
-    prop.set_f32(atom, Role::App, 1, 1.).unwrap();
-    prop.set_f32(atom, Role::App, 2, 0.51).unwrap();
-    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
-
-    let prop = node.get_property("alert_color").unwrap();
-    prop.set_f32(atom, Role::App, 0, 0.56).unwrap();
-    prop.set_f32(atom, Role::App, 1, 0.61).unwrap();
-    prop.set_f32(atom, Role::App, 2, 1.).unwrap();
-    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
-
     let prop = node.get_property("sep_color").unwrap();
     let prop = node.get_property("sep_color").unwrap();
     prop.set_f32(atom, Role::App, 0, 0.4).unwrap();
     prop.set_f32(atom, Role::App, 0, 0.4).unwrap();
     prop.set_f32(atom, Role::App, 1, 0.4).unwrap();
     prop.set_f32(atom, Role::App, 1, 0.4).unwrap();

+ 0 - 12
bin/app/src/app/schema/menu/contact.rs

@@ -1280,18 +1280,6 @@ pub async fn make(
     prop.set_f32(atom, Role::App, 2, 1.).unwrap();
     prop.set_f32(atom, Role::App, 2, 1.).unwrap();
     prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     prop.set_f32(atom, Role::App, 3, 1.).unwrap();
 
 
-    let prop = node.get_property("active_color").unwrap();
-    prop.set_f32(atom, Role::App, 0, 0.36).unwrap();
-    prop.set_f32(atom, Role::App, 1, 1.).unwrap();
-    prop.set_f32(atom, Role::App, 2, 0.51).unwrap();
-    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
-
-    let prop = node.get_property("alert_color").unwrap();
-    prop.set_f32(atom, Role::App, 0, 0.56).unwrap();
-    prop.set_f32(atom, Role::App, 1, 0.61).unwrap();
-    prop.set_f32(atom, Role::App, 2, 1.).unwrap();
-    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
-
     let prop = node.get_property("sep_color").unwrap();
     let prop = node.get_property("sep_color").unwrap();
     prop.set_f32(atom, Role::App, 0, 0.4).unwrap();
     prop.set_f32(atom, Role::App, 0, 0.4).unwrap();
     prop.set_f32(atom, Role::App, 1, 0.4).unwrap();
     prop.set_f32(atom, Role::App, 1, 0.4).unwrap();

+ 4 - 12
bin/app/src/app/schema/menu/mod.rs

@@ -419,18 +419,6 @@ pub async fn make(
     prop.set_f32(atom, Role::App, 2, 1.).unwrap();
     prop.set_f32(atom, Role::App, 2, 1.).unwrap();
     prop.set_f32(atom, Role::App, 3, 1.).unwrap();
     prop.set_f32(atom, Role::App, 3, 1.).unwrap();
 
 
-    let prop = node.get_property("active_color").unwrap();
-    prop.set_f32(atom, Role::App, 0, 0.36).unwrap();
-    prop.set_f32(atom, Role::App, 1, 1.).unwrap();
-    prop.set_f32(atom, Role::App, 2, 0.51).unwrap();
-    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
-
-    let prop = node.get_property("alert_color").unwrap();
-    prop.set_f32(atom, Role::App, 0, 0.56).unwrap();
-    prop.set_f32(atom, Role::App, 1, 0.61).unwrap();
-    prop.set_f32(atom, Role::App, 2, 1.).unwrap();
-    prop.set_f32(atom, Role::App, 3, 1.).unwrap();
-
     let prop = node.get_property("sep_color").unwrap();
     let prop = node.get_property("sep_color").unwrap();
     prop.set_f32(atom, Role::App, 0, 0.4).unwrap();
     prop.set_f32(atom, Role::App, 0, 0.4).unwrap();
     prop.set_f32(atom, Role::App, 1, 0.4).unwrap();
     prop.set_f32(atom, Role::App, 1, 0.4).unwrap();
@@ -456,6 +444,8 @@ pub async fn make(
     let sg_root = app.sg_root.clone();
     let sg_root = app.sg_root.clone();
     let menu_is_visible = PropertyBool::wrap(&layer_node, Role::App, "is_visible", 0).unwrap();
     let menu_is_visible = PropertyBool::wrap(&layer_node, Role::App, "is_visible", 0).unwrap();
     let renderer = app.renderer.clone();
     let renderer = app.renderer.clone();
+    let role1_group = node.get_property("role1_group").unwrap();
+    let role2_group = node.get_property("role2_group").unwrap();
     let listen_click = app.ex.spawn(async move {
     let listen_click = app.ex.spawn(async move {
         while let Ok(data) = recvr.recv().await {
         while let Ok(data) = recvr.recv().await {
             let channel: String = deserialize(&data).unwrap();
             let channel: String = deserialize(&data).unwrap();
@@ -463,6 +453,8 @@ pub async fn make(
             if let Some(node) = sg_root.lookup_node(path) {
             if let Some(node) = sg_root.lookup_node(path) {
                 let atom = &mut renderer.make_guard(gfxtag!("channel_clicked"));
                 let atom = &mut renderer.make_guard(gfxtag!("channel_clicked"));
                 info!(target: "app::menu", "clicked: {channel}!");
                 info!(target: "app::menu", "clicked: {channel}!");
+                role1_group.remove_str_item(atom, Role::App, &channel);
+                role2_group.remove_str_item(atom, Role::App, &channel);
                 node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
                 node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
                 menu_is_visible.set(atom, false);
                 menu_is_visible.set(atom, false);
             }
             }

+ 5 - 19
bin/app/src/main.rs

@@ -329,26 +329,12 @@ async fn load_plugins(
                 continue
                 continue
             }
             }
 
 
-            /*
-            // TODO: add coloring to menu items
-
-            let node_path = format!("/window/content/menu_layer/{channel}_channel_label");
-            let menu_label = sg_root2.lookup_node(&node_path).unwrap();
-            let prop = menu_label.get_property("text_color").unwrap();
-            if msg.contains(&darkirc_nick.get()) {
-                // Nick highlight
-                prop.set_f32(atom, Role::App, 0, 0.56).unwrap();
-                prop.set_f32(atom, Role::App, 1, 0.61).unwrap();
-                prop.set_f32(atom, Role::App, 2, 1.).unwrap();
-                prop.set_f32(atom, Role::App, 3, 1.).unwrap();
-            } else {
-                // Normal channel activity
-                prop.set_f32(atom, Role::App, 0, 0.36).unwrap();
-                prop.set_f32(atom, Role::App, 1, 1.).unwrap();
-                prop.set_f32(atom, Role::App, 2, 0.51).unwrap();
-                prop.set_f32(atom, Role::App, 3, 1.).unwrap();
+            let menu_node = sg_root2.lookup_node("/window/content/menu_layer/main_menu").unwrap();
+            let group_name = if msg.contains(&darkirc_nick.get()) { "role2_group" } else { "role1_group" };
+            let group = menu_node.get_property(group_name).unwrap();
+            if !group.get_str_vec().unwrap().contains(&channel) {
+                group.push_str(atom, Role::App, &channel).unwrap();
             }
             }
-            */
         }
         }
     });
     });
 
 

+ 17 - 0
bin/app/src/prop/mod.rs

@@ -967,6 +967,23 @@ impl Property {
         }
         }
     }
     }
 
 
+    // Remove by item
+
+    pub fn remove_str_item(
+        self: &Arc<Self>,
+        atom: &mut PropertyAtomicGuard,
+        role: Role,
+        item: &str,
+    ) -> Option<usize> {
+        for i in 0..self.get_len() {
+            if self.get_str(i).unwrap() == item {
+                self.remove_str(atom, role, i).unwrap();
+                return Some(i);
+            }
+        }
+        None
+    }
+
     // Get
     // Get
 
 
     pub fn is_bounded(&self) -> bool {
     pub fn is_bounded(&self) -> bool {

+ 32 - 109
bin/app/src/ui/menu/mod.rs

@@ -24,7 +24,7 @@ use miniquad::{MouseButton, TouchPhase};
 use parking_lot::Mutex as SyncMutex;
 use parking_lot::Mutex as SyncMutex;
 use rand::{rngs::OsRng, Rng};
 use rand::{rngs::OsRng, Rng};
 use std::{
 use std::{
-    collections::{HashMap, VecDeque},
+    collections::{HashMap, HashSet, VecDeque},
     io::Read,
     io::Read,
     sync::{
     sync::{
         atomic::{AtomicBool, Ordering},
         atomic::{AtomicBool, Ordering},
@@ -60,12 +60,6 @@ const MENU_ICON_OFFSET: f32 = 24.;
 macro_rules! d { ($($arg:tt)*) => { debug!(target: "ui::menu", $($arg)*); } }
 macro_rules! d { ($($arg:tt)*) => { debug!(target: "ui::menu", $($arg)*); } }
 macro_rules! t { ($($arg:tt)*) => { trace!(target: "ui::menu", $($arg)*); } }
 macro_rules! t { ($($arg:tt)*) => { trace!(target: "ui::menu", $($arg)*); } }
 
 
-#[derive(Clone, Copy, PartialEq, Eq)]
-enum ItemStatus {
-    Active,
-    Alert,
-}
-
 #[derive(Clone)]
 #[derive(Clone)]
 struct TouchInfo {
 struct TouchInfo {
     start_scroll: f32,
     start_scroll: f32,
@@ -139,8 +133,10 @@ pub struct Menu {
     bg_color: PropertyColor,
     bg_color: PropertyColor,
     sep_size: PropertyFloat32,
     sep_size: PropertyFloat32,
     sep_color: PropertyColor,
     sep_color: PropertyColor,
-    active_color: PropertyColor,
-    alert_color: PropertyColor,
+    role1_color: PropertyColor,
+    role1_group: PropertyPtr,
+    role2_color: PropertyColor,
+    role2_group: PropertyPtr,
     fade_zone: PropertyFloat32,
     fade_zone: PropertyFloat32,
     window_scale: PropertyFloat32,
     window_scale: PropertyFloat32,
 
 
@@ -158,8 +154,6 @@ pub struct Menu {
     is_edit_mode: AtomicBool,
     is_edit_mode: AtomicBool,
 
 
     parent_rect: SyncMutex<Option<Rectangle>>,
     parent_rect: SyncMutex<Option<Rectangle>>,
-    item_states: SyncMutex<HashMap<String, ItemStatus>>,
-
     saved_items: SyncMutex<Option<Vec<String>>>,
     saved_items: SyncMutex<Option<Vec<String>>>,
 }
 }
 
 
@@ -184,8 +178,10 @@ impl Menu {
         let bg_color = PropertyColor::wrap(node_ref, Role::Internal, "bg_color").unwrap();
         let bg_color = PropertyColor::wrap(node_ref, Role::Internal, "bg_color").unwrap();
         let sep_size = PropertyFloat32::wrap(node_ref, Role::Internal, "sep_size", 0).unwrap();
         let sep_size = PropertyFloat32::wrap(node_ref, Role::Internal, "sep_size", 0).unwrap();
         let sep_color = PropertyColor::wrap(node_ref, Role::Internal, "sep_color").unwrap();
         let sep_color = PropertyColor::wrap(node_ref, Role::Internal, "sep_color").unwrap();
-        let active_color = PropertyColor::wrap(node_ref, Role::Internal, "active_color").unwrap();
-        let alert_color = PropertyColor::wrap(node_ref, Role::Internal, "alert_color").unwrap();
+        let role1_color = PropertyColor::wrap(node_ref, Role::Internal, "role1_color").unwrap();
+        let role1_group = node_ref.get_property("role1_group").unwrap();
+        let role2_color = PropertyColor::wrap(node_ref, Role::Internal, "role2_color").unwrap();
+        let role2_group = node_ref.get_property("role2_group").unwrap();
 
 
         let fade_zone = PropertyFloat32::wrap(node_ref, Role::Internal, "fade_zone", 0).unwrap();
         let fade_zone = PropertyFloat32::wrap(node_ref, Role::Internal, "fade_zone", 0).unwrap();
 
 
@@ -215,8 +211,10 @@ impl Menu {
             bg_color,
             bg_color,
             sep_size,
             sep_size,
             sep_color,
             sep_color,
-            active_color,
-            alert_color,
+            role1_color,
+            role1_group,
+            role2_color,
+            role2_group,
             fade_zone,
             fade_zone,
             window_scale,
             window_scale,
             mouse_pos: SyncMutex::new(Point::new(0., 0.)),
             mouse_pos: SyncMutex::new(Point::new(0., 0.)),
@@ -232,7 +230,6 @@ impl Menu {
             speed: AtomicF32::new(0.),
             speed: AtomicF32::new(0.),
             is_edit_mode: AtomicBool::new(false),
             is_edit_mode: AtomicBool::new(false),
             parent_rect: SyncMutex::new(None),
             parent_rect: SyncMutex::new(None),
-            item_states: SyncMutex::new(HashMap::new()),
             saved_items: SyncMutex::new(None),
             saved_items: SyncMutex::new(None),
         });
         });
 
 
@@ -270,11 +267,8 @@ impl Menu {
 
 
     async fn handle_selection(&self, item_idx: usize) {
     async fn handle_selection(&self, item_idx: usize) {
         if item_idx < self.items.get_len() {
         if item_idx < self.items.get_len() {
-            let item_name = self.items.get_str(item_idx).unwrap();
-
-            self.item_states.lock().remove(&item_name);
-
             let node = self.node.upgrade().unwrap();
             let node = self.node.upgrade().unwrap();
+            let item_name = self.items.get_str(item_idx).unwrap();
             let data = serialize(&item_name);
             let data = serialize(&item_name);
             node.trigger("select", data).await.unwrap();
             node.trigger("select", data).await.unwrap();
         }
         }
@@ -342,14 +336,19 @@ impl Menu {
         let padding_y = self.padding.get_f32(1).unwrap();
         let padding_y = self.padding.get_f32(1).unwrap();
         let handle_padding = self.handle_padding.get();
         let handle_padding = self.handle_padding.get();
         let text_color = self.text_color.get();
         let text_color = self.text_color.get();
-        let active_color = self.active_color.get();
-        let alert_color = self.alert_color.get();
+        let role1_color = self.role1_color.get();
+        let role2_color = self.role2_color.get();
         let bg_color = self.bg_color.get();
         let bg_color = self.bg_color.get();
         let sep_size = self.sep_size.get();
         let sep_size = self.sep_size.get();
         let sep_color = self.sep_color.get();
         let sep_color = self.sep_color.get();
         let fade_distance = self.fade_zone.get();
         let fade_distance = self.fade_zone.get();
         let window_scale = self.window_scale.get();
         let window_scale = self.window_scale.get();
 
 
+        let role1_set: HashSet<String> =
+            self.role1_group.get_str_vec().unwrap_or_default().into_iter().collect();
+        let role2_set: HashSet<String> =
+            self.role2_group.get_str_vec().unwrap_or_default().into_iter().collect();
+
         let num_items = self.items.get_len();
         let num_items = self.items.get_len();
 
 
         // Get items and reorder if dragging
         // Get items and reorder if dragging
@@ -382,7 +381,6 @@ impl Menu {
         sep_mesh.draw_filled_box(&Rectangle::new(0., 0., rect.w, sep_size), sep_color);
         sep_mesh.draw_filled_box(&Rectangle::new(0., 0., rect.w, sep_size), sep_color);
         let sep_mesh = sep_mesh.alloc(&self.renderer).draw_untextured();
         let sep_mesh = sep_mesh.alloc(&self.renderer).draw_untextured();
 
 
-        let item_states = self.item_states.lock();
         let is_edit_mode = self.is_edit_mode.load(Ordering::Relaxed);
         let is_edit_mode = self.is_edit_mode.load(Ordering::Relaxed);
         let edit_offset = if is_edit_mode { handle_padding } else { 0.0 };
         let edit_offset = if is_edit_mode { handle_padding } else { 0.0 };
 
 
@@ -408,10 +406,12 @@ impl Menu {
         for idx in 0..num_items {
         for idx in 0..num_items {
             let item_text = items_list[idx].clone();
             let item_text = items_list[idx].clone();
 
 
-            let base_color = match item_states.get(&item_text) {
-                Some(ItemStatus::Active) => active_color,
-                Some(ItemStatus::Alert) => alert_color,
-                _ => text_color,
+            let base_color = if role2_set.contains(&item_text) {
+                role2_color
+            } else if role1_set.contains(&item_text) {
+                role1_color
+            } else {
+                text_color
             };
             };
 
 
             // Apply fade effect in the configured fade zone
             // Apply fade effect in the configured fade zone
@@ -567,72 +567,6 @@ impl Menu {
         }
         }
     }
     }
 
 
-    async fn process_mark_active_method(me: &Weak<Self>, sub: &MethodCallSub) -> bool {
-        let Ok(method_call) = sub.receive().await else {
-            d!("Event relayer closed");
-            return false
-        };
-
-        d!("method called: mark_active({method_call:?})");
-        assert!(method_call.send_res.is_none());
-
-        fn decode_data(data: &[u8]) -> std::io::Result<String> {
-            use std::io::Cursor;
-            let mut cur = Cursor::new(&data);
-            let item_name = String::decode(&mut cur)?;
-            Ok(item_name)
-        }
-
-        let Ok(item_name) = decode_data(&method_call.data) else {
-            d!("mark_active() method invalid arg data");
-            return true
-        };
-
-        let Some(self_) = me.upgrade() else {
-            d!("Self destroyed");
-            return true
-        };
-
-        self_.item_states.lock().insert(item_name, ItemStatus::Active);
-        let atom = &mut self_.renderer.make_guard(gfxtag!("Menu::mark_active"));
-        self_.redraw(atom);
-
-        true
-    }
-
-    async fn process_mark_alert_method(me: &Weak<Self>, sub: &MethodCallSub) -> bool {
-        let Ok(method_call) = sub.receive().await else {
-            d!("Event relayer closed");
-            return false
-        };
-
-        d!("method called: mark_alert({method_call:?})");
-        assert!(method_call.send_res.is_none());
-
-        fn decode_data(data: &[u8]) -> std::io::Result<String> {
-            use std::io::Cursor;
-            let mut cur = Cursor::new(&data);
-            let item_name = String::decode(&mut cur)?;
-            Ok(item_name)
-        }
-
-        let Ok(item_name) = decode_data(&method_call.data) else {
-            d!("mark_alert() method invalid arg data");
-            return true
-        };
-
-        let Some(self_) = me.upgrade() else {
-            d!("Self destroyed");
-            return true
-        };
-
-        self_.item_states.lock().insert(item_name, ItemStatus::Alert);
-        let atom = &mut self_.renderer.make_guard(gfxtag!("Menu::mark_alert"));
-        self_.redraw(atom);
-
-        true
-    }
-
     /// Cancels edit mode changes, reverting any modifications made during edit mode
     /// Cancels edit mode changes, reverting any modifications made during edit mode
     async fn process_cancel_method(me: &Weak<Self>, sub: &MethodCallSub) -> bool {
     async fn process_cancel_method(me: &Weak<Self>, sub: &MethodCallSub) -> bool {
         let Ok(method_call) = sub.receive().await else {
         let Ok(method_call) = sub.receive().await else {
@@ -723,20 +657,6 @@ impl UIObject for Menu {
             }
             }
         });
         });
 
 
-        let method_sub = node_ref.subscribe_method_call("mark_active").unwrap();
-        let me2 = me.clone();
-        let mark_active_task =
-            ex.spawn(
-                async move { while Self::process_mark_active_method(&me2, &method_sub).await {} },
-            );
-
-        let method_sub = node_ref.subscribe_method_call("mark_alert").unwrap();
-        let me2 = me.clone();
-        let mark_alert_task =
-            ex.spawn(
-                async move { while Self::process_mark_alert_method(&me2, &method_sub).await {} },
-            );
-
         let method_sub = node_ref.subscribe_method_call("cancel_edit").unwrap();
         let method_sub = node_ref.subscribe_method_call("cancel_edit").unwrap();
         let me2 = me.clone();
         let me2 = me.clone();
         let cancel_task =
         let cancel_task =
@@ -762,9 +682,12 @@ impl UIObject for Menu {
         on_modify.when_change(self.bg_color.prop(), redraw);
         on_modify.when_change(self.bg_color.prop(), redraw);
         on_modify.when_change(self.sep_size.prop(), redraw);
         on_modify.when_change(self.sep_size.prop(), redraw);
         on_modify.when_change(self.sep_color.prop(), redraw);
         on_modify.when_change(self.sep_color.prop(), redraw);
+        on_modify.when_change(self.role1_color.prop(), redraw);
+        on_modify.when_change(self.role1_group.clone(), redraw);
+        on_modify.when_change(self.role2_color.prop(), redraw);
+        on_modify.when_change(self.role2_group.clone(), redraw);
 
 
-        let mut tasks =
-            vec![motion_task, mark_active_task, mark_alert_task, cancel_task, done_task];
+        let mut tasks = vec![motion_task, cancel_task, done_task];
         tasks.append(&mut on_modify.tasks);
         tasks.append(&mut on_modify.tasks);
         *self.tasks.lock() = tasks;
         *self.tasks.lock() = tasks;
     }
     }