From f26f1fe2f21e185aa0b0e8b4a94d28913292100e Mon Sep 17 00:00:00 2001 From: enx01 Date: Fri, 14 Nov 2025 15:07:02 +0100 Subject: [PATCH] [wip] friends list --- src/main.rs | 10 +- src/net/networkmanager.rs | 2 +- src/ui/elements/mod.rs | 1 + src/ui/elements/start_menu.rs | 24 ++- .../start_menu_elements/friends_list.rs | 163 ++++++++++++++++++ src/ui/elements/start_menu_elements/mod.rs | 1 + 6 files changed, 189 insertions(+), 12 deletions(-) create mode 100644 src/ui/elements/start_menu_elements/friends_list.rs create mode 100644 src/ui/elements/start_menu_elements/mod.rs diff --git a/src/main.rs b/src/main.rs index 9df98dc..5c52a30 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,16 +8,16 @@ use crate::{ start_menu::StartMenu, }, utils::assets::*, - windows::window_manager::{self, WindowManager}, + windows::window_manager::WindowManager, }, }; use std::{env, path}; use ggez::{ - Context, GameError, GameResult, event, - graphics::{self, Color, DrawParam, FontData, Image}, - input::mouse::{self}, - mint::Point2, + event, graphics::{self, Color, DrawParam, FontData, Image}, input::mouse::{self}, mint::Point2, + Context, + GameError, + GameResult, }; pub struct State { diff --git a/src/net/networkmanager.rs b/src/net/networkmanager.rs index ca33f83..cc3765e 100644 --- a/src/net/networkmanager.rs +++ b/src/net/networkmanager.rs @@ -10,7 +10,7 @@ use std::{ use once_cell::sync::Lazy; use reqwest::Client; use serde::{Deserialize, Serialize}; -use tokio::{runtime::Runtime, time}; +use tokio::runtime::Runtime; pub(crate) static NETWORK_MANAGER: Lazy> = Lazy::new(|| Arc::new(NetworkManager::new())); diff --git a/src/ui/elements/mod.rs b/src/ui/elements/mod.rs index 8bce88f..b9bf4a8 100644 --- a/src/ui/elements/mod.rs +++ b/src/ui/elements/mod.rs @@ -1,2 +1,3 @@ pub(crate) mod button; pub(crate) mod start_menu; +mod start_menu_elements; diff --git a/src/ui/elements/start_menu.rs b/src/ui/elements/start_menu.rs index f271184..754f2f6 100644 --- a/src/ui/elements/start_menu.rs +++ b/src/ui/elements/start_menu.rs @@ -1,18 +1,20 @@ use ggez::{ - Context, GameResult, - context::Has, - graphics::{Canvas, Color, DrawParam, Drawable, Image, Text, TextFragment}, - input::mouse, + graphics::{Canvas, Color, DrawParam, Drawable, Image, Text, TextFragment}, input::mouse + , mint::Point2, + Context, + GameResult, }; -use tokio::runtime::Runtime; -use crate::net::networkmanager::{self, NETWORK_MANAGER, UserName}; +use crate::net::networkmanager::NETWORK_MANAGER; use crate::ui::{ elements::button::*, utils::assets::get_asset, windows::window_manager::WindowManager, }; +use crate::ui::elements::start_menu_elements::friends_list::FriendsList; + + pub struct StartMenu { visible: bool, background: Image, @@ -21,6 +23,7 @@ pub struct StartMenu { profile_button: Button, shutdown_button: Button, username: Text, + friends_list: FriendsList, } impl StartMenu { @@ -48,6 +51,8 @@ impl StartMenu { let username = Text::new(frag); + let friends_list = FriendsList::new(ctx)?; + let visible = false; Ok(StartMenu { visible, @@ -57,6 +62,7 @@ impl StartMenu { profile_button, shutdown_button, username, + friends_list, }) } @@ -88,6 +94,11 @@ impl StartMenu { } pub fn update(&mut self, ctx: &mut Context, wm: &mut WindowManager) { + if !self.visible { + return; + } + self.friends_list.update(ctx); + if ctx.mouse.button_just_pressed(mouse::MouseButton::Left) { let mut res = self.shutdown_button.update(&ctx.mouse); if res { @@ -122,6 +133,7 @@ impl StartMenu { self.shutdown_button.draw(canvas); self.username .draw(canvas, DrawParam::default().dest([64.0, 222.5])); + self.friends_list.draw(canvas); } } } diff --git a/src/ui/elements/start_menu_elements/friends_list.rs b/src/ui/elements/start_menu_elements/friends_list.rs new file mode 100644 index 0000000..bce2053 --- /dev/null +++ b/src/ui/elements/start_menu_elements/friends_list.rs @@ -0,0 +1,163 @@ +use std::collections::VecDeque; +use ggez::{graphics, Context, GameResult}; +use ggez::event::MouseButton; +use ggez::graphics::{Canvas, Color, DrawParam, Drawable, Mesh, Rect, Text, TextFragment}; +use ggez::input::keyboard; +use ggez::input::keyboard::KeyCode; +use ggez::mint::Point2; + + +pub struct FriendsList { + search_bar: Mesh, + friends: Vec, + start_index: usize, + visible_count: usize, + scroll_position: f32, + username_height: f32, + dragging: bool, + scroll_bar: Mesh, + last_mouse_y: f32, +} + +impl FriendsList { + pub fn new(ctx: &mut Context) -> GameResult { + let search_bar = Mesh::new_rectangle( + ctx, + graphics::DrawMode::fill(), + { + let rect_x = 50.0; + let rect_y = 275.0; + let rect_width = 225.0; + let rect_height = 20.0; + Rect::new(rect_x, rect_y, rect_width, rect_height) + }, + Color::from_rgb(168, 168, 168), + )?; + let mut friends: Vec = Vec::new(); + friends.push(String::from("bob")); + friends.push(String::from("bob2")); + friends.push(String::from("bob3")); + friends.push(String::from("bob4")); + friends.push(String::from("bob5")); + friends.push(String::from("bob6")); + friends.push(String::from("bob7")); + friends.push(String::from("bob8")); + friends.push(String::from("bob9")); + friends.push(String::from("bob10")); + let scroll_position = 0.0; + + Ok(FriendsList { + search_bar, + friends, + start_index: 3, + visible_count: 5, + scroll_position, + dragging: false, + last_mouse_y: 0.0, + username_height: 34.0, + scroll_bar: Mesh::new_rectangle( + ctx, + graphics::DrawMode::fill(), + { + let rect_x = 250.0; + let rect_y = 280.0; + let rect_width = 10.0; + let rect_height = 100.0; + Rect::new(rect_x, rect_y, rect_width, rect_height) + }, + Color::from_rgb(168, 168, 168), + )?, + }) + } + + pub fn update(&mut self, ctx: &mut Context) { + if ctx.mouse.button_pressed(MouseButton::Left) { + self.mouse_button_down_event(ctx); + } else { + self.dragging = false; + } + + // Update scroll bar position and size + let total_usernames = self.friends.len(); + let scrollable_area = total_usernames as f32 * self.username_height; + let visible_area = self.visible_count as f32 * self.username_height; + + // Handle case with zero usernames or less than visible count + if total_usernames == 0 { + self.scroll_bar = Mesh::new_rectangle( + ctx, + graphics::DrawMode::fill(), + { + let rect_x = 250.0; + let rect_y = 280.0; + let rect_width = 10.0; + let rect_height = 100.0; + Rect::new(rect_x, rect_y, rect_width, rect_height) + }, + Color::from_rgb(168, 168, 168), + ).expect("Can't update friends"); + return; + } + + let scroll_height = (visible_area / scrollable_area).min(1.0) * 100.0; + let scroll_y = 280.0 + (self.start_index as f32 * 34.0).max(0.0); + + self.scroll_bar = Mesh::new_rectangle( + ctx, + graphics::DrawMode::fill(), + { + let rect_x = 250.0; + let rect_y = scroll_y; + let rect_width = 10.0; + let rect_height = scroll_height; + Rect::new(rect_x, rect_y, rect_width, rect_height) + }, + Color::from_rgb(168, 168, 168), + ).expect("Can't update friends"); + + // Handle drag logic + if self.dragging { + println!("Dragging"); + let mouse_delta = ctx.mouse.delta(); + let delta_y = mouse_delta.y; + + let new_start_index = self.start_index as f32 + delta_y / (100.0 - scroll_height) * total_usernames as f32; + + self.start_index = new_start_index.clamp(0.0, (total_usernames as f32 - self.visible_count as f32)).round() as usize; + } + } + + fn mouse_button_down_event(&mut self, ctx: &mut Context) { + let mouse_pos = ctx.mouse.position(); + if let Some(dimensions) = self.scroll_bar.dimensions(ctx) { + println!("{:?}", self.scroll_bar.dimensions(ctx)); + if dimensions.contains(mouse_pos) { + self.dragging = true; + self.last_mouse_y = mouse_pos.y; + return; + } + } + } + + + pub fn draw(&mut self, canvas: &mut Canvas) { + // Draw the search bar + canvas.draw(&self.search_bar, DrawParam::default().dest([0.0,0.0])); + + // Determine the range of usernames to display + let end_index = std::cmp::min(self.start_index + self.visible_count, self.friends.len()); + + // Draw each username in the visible range + for (i, username) in self.friends[self.start_index..end_index].iter().enumerate() { + let frag = TextFragment::new(username) + .font("msw98-reg") + .scale(13.0) + .color(Color::BLACK); + let text = Text::new(frag); + canvas.draw(&text, DrawParam::default().dest([15.0, (i as f32 * 34.0 + 300.0)]),); // Adjust x-offset for text + } + + // Draw the scroll bar + canvas.draw(&self.scroll_bar, DrawParam::default().dest([0.0, 0.0])); + } +} \ No newline at end of file diff --git a/src/ui/elements/start_menu_elements/mod.rs b/src/ui/elements/start_menu_elements/mod.rs new file mode 100644 index 0000000..1491c1f --- /dev/null +++ b/src/ui/elements/start_menu_elements/mod.rs @@ -0,0 +1 @@ +pub(crate) mod friends_list; \ No newline at end of file