app: cleanup menu select logic, now we can select channels with the new menu

This commit is contained in:
jkds
2026-01-16 11:17:22 +01:00
parent ae3cb958ac
commit a54a982b05
3 changed files with 48 additions and 22 deletions

View File

@@ -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)],
)

View File

@@ -16,6 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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);

View File

@@ -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<usize> {
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;
}
}