diff --git a/bin/app/src/app/node.rs b/bin/app/src/app/node.rs index 35213ba21..ee2f400be 100644 --- a/bin/app/src/app/node.rs +++ b/bin/app/src/app/node.rs @@ -667,7 +667,7 @@ pub fn create_menu(name: &str) -> SceneNode { node.add_property(prop).unwrap(); node.add_signal( - "selected", + "select", "Item selected", vec![("item", "Selected item name", CallArgType::Str)], ) diff --git a/bin/app/src/app/schema/menu.rs b/bin/app/src/app/schema/menu.rs index d2a281893..8d0615125 100644 --- a/bin/app/src/app/schema/menu.rs +++ b/bin/app/src/app/schema/menu.rs @@ -16,6 +16,9 @@ * along with this program. If not, see . */ +use darkfi_serial::deserialize; + +use super::{ColorScheme, CHANNELS, COLOR_SCHEME}; use crate::{ app::{ node::{ @@ -33,8 +36,6 @@ use crate::{ util::i18n::I18nBabelFish, }; -use super::{ColorScheme, CHANNELS, COLOR_SCHEME}; - #[cfg(any(target_os = "android", feature = "emulate-android"))] mod android_ui_consts { pub const CHANNEL_LABEL_X: f32 = 40.; @@ -210,11 +211,33 @@ pub async fn make(app: &App, content: SceneNodePtr, i18n_fish: &I18nBabelFish) { let label = "#".to_string() + channel; prop.push_str(atom, Role::App, label).unwrap(); } - for channel in - ["john", "stacy", "barry", "steve", "obombo", "xyz", "lunar", "fren", "anon", "anon1"] - { - prop.push_str(atom, Role::App, channel).unwrap(); - } + //for channel in + // ["john", "stacy", "barry", "steve", "obombo", "xyz", "lunar", "fren", "anon", "anon1"] + //{ + // prop.push_str(atom, Role::App, channel).unwrap(); + //} + + let (slot, recvr) = Slot::new("menu_clicked"); + node.register("select", slot).unwrap(); + let sg_root = app.sg_root.clone(); + let menu_is_visible = PropertyBool::wrap(&layer_node, Role::App, "is_visible", 0).unwrap(); + let render_api = app.render_api.clone(); + let listen_click = app.ex.spawn(async move { + while let Ok(data) = recvr.recv().await { + let item_name: String = deserialize(&data).unwrap(); + // use if let here + let channel = item_name.strip_prefix('#').unwrap(); + let chatview_path = format!("/window/content/{}_chat_layer", channel); + let chatview_node = sg_root.lookup_node(chatview_path).unwrap(); + + let atom = &mut render_api.make_guard(gfxtag!("channel_clicked")); + info!(target: "app::menu", "clicked: {channel}!"); + chatview_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap(); + menu_is_visible.set(atom, false); + //set_normal_color(atom); + } + }); + app.tasks.lock().unwrap().push(listen_click); let node = node.setup(|me| Menu::new(me, window_scale.clone(), app.render_api.clone())).await; layer_node.link(node); diff --git a/bin/app/src/ui/menu.rs b/bin/app/src/ui/menu.rs index 6b629d3f3..6fee90154 100644 --- a/bin/app/src/ui/menu.rs +++ b/bin/app/src/ui/menu.rs @@ -19,6 +19,7 @@ use async_trait::async_trait; use atomic_float::AtomicF32; use darkfi::system::CondVar; +use darkfi_serial::serialize; use miniquad::{MouseButton, TouchPhase}; use parking_lot::Mutex as SyncMutex; use rand::{rngs::OsRng, Rng}; @@ -179,29 +180,35 @@ impl Menu { Pimpl::Menu(self_) } + /// Height of a single item fn get_item_height(&self) -> f32 { self.font_size.get() + self.padding.get_f32(1).unwrap() * 2.0 } + /// Height of the content without the overscroll + fn content_height(&self) -> f32 { + self.items.get_len() as f32 * self.get_item_height() + } fn get_selected_item_index(&self, click_y: f32) -> Option { let rect = self.rect.get(); let scroll = self.scroll.get(); - let item_height = self.get_item_height(); - let content_y = click_y - rect.y - scroll; - - if content_y >= 0. && content_y < self.items.get_len() as f32 * item_height { - Some((content_y / item_height) as usize) - } else { - None + // Scroll is positive value so to translate click into content, we must add the scroll. + let content_y = click_y + scroll - rect.y; + if content_y < 0. || content_y > self.content_height() { + return None } + + let item_height = self.get_item_height(); + Some((content_y / item_height) as usize) } async fn handle_selection(&self, item_idx: usize) { if item_idx < self.items.get_len() { let item_name = self.items.get_str(item_idx).unwrap(); let node = self.node.upgrade().unwrap(); - node.trigger("selected", item_name.as_bytes().to_vec()).await.unwrap(); + let data = serialize(&item_name); + node.trigger("select", data).await.unwrap(); } } @@ -447,8 +454,7 @@ impl UIObject for Menu { return false } - let click_y = mouse_pos.y - rect.y; - if let Some(item_idx) = self.get_selected_item_index(click_y) { + if let Some(item_idx) = self.get_selected_item_index(mouse_pos.y) { self.handle_selection(item_idx).await; true } else { @@ -540,10 +546,7 @@ impl UIObject for Menu { }; if is_tap { - let rect = self.rect.get(); - let click_y = touch_pos.y - rect.y; - - if let Some(item_idx) = self.get_selected_item_index(click_y) { + if let Some(item_idx) = self.get_selected_item_index(touch_pos.y) { self.handle_selection(item_idx).await; } }