use iris::prelude::*; use len_fns::*; use openworm::net::{ClientMsg, Msg}; use winit::dpi::{LogicalPosition, LogicalSize}; use crate::{ Client, net::{ConnectInfo, NetSender, connect}, }; #[derive(Eq, PartialEq, Hash, Clone)] pub struct Submit; #[derive(Eq, PartialEq, Hash, Clone)] pub struct Edited; impl DefaultEvent for Submit { type Data = (); } impl DefaultEvent for Edited { type Data = (); } pub fn init(client: &mut Client) { login_screen(client).set_root(&mut client.ui); } pub fn main_view(client: &mut Client, network: NetSender) -> WidgetId { let msg_panel = msg_panel(client, network); let side_bar = rect(Color::BLACK.brighter(0.05)).width(80); let bg = ( image(include_bytes!("./assets/fuit.jpg")), rect(Color::BLACK.alpha((0.8 * 255.0) as u8)), ).stack(); (side_bar, msg_panel) .span(Dir::RIGHT) .background(bg) .add(&mut client.ui) .any() } pub fn error(ui: &mut Ui, msg: &str) -> WidgetId { text(msg) .size(20) .color(Color::RED.brighter(0.3)) .pad(10) .add(ui) .any() } fn login_screen(client: &mut Client) -> WidgetId { let Client { ui, handle, data, .. } = client; let mut field = |name| text(name).editable().size(20).add(ui); let ip = field(&data.ip); let username = field(&data.username); // let password = field("password"); let fbx = |field: WidgetId| { field .clone() .pad(10) .background(rect(Color::BLACK.brighter(0.1)).radius(15)) .on(CursorSense::click(), focus_other(field)) }; // I LAV NOT HAVING ERGONOMIC CLONES let handle = handle.clone(); let ip_ = ip.clone(); let username_ = username.clone(); let color = Color::GREEN; let submit = rect(color) .radius(15) .id_on(CursorSense::click(), move |id, client: &mut Client, _| { client.ui[id].color = color.darker(0.3); let ip = client.ui[&ip_].content(); let username = client.ui[&username_].content(); connect(handle.clone(), ConnectInfo { ip, username }); }) .height(40); let modal = ( text("login").size(30), fbx(ip .id_on(Edited, |id, client: &mut Client, _| { client.data.ip = client.ui[id].content(); }) .add(ui)), fbx(username .id_on(Edited, |id, client: &mut Client, _| { client.data.username = client.ui[id].content(); }) .add(ui)), // fbx(password), submit, ) .span(Dir::DOWN) .gap(10) .pad(15) .background(rect(Color::BLACK.brighter(0.2)).radius(15)) .width(400) .align(Align::CENTER); let err = WidgetPtr::default().add(ui); client.error = Some(err.clone()); (modal, err.align(Align::TOP_CENTER)).stack().add(ui).any() } pub fn msg_widget(msg: Msg) -> impl WidgetLike { let content = text(msg.content) .editable() .size(20) .text_align(Align::LEFT) .wrap(true) .id_on(CursorSense::click(), |i, c, d| focus(i.clone(), c, d)); let header = text(msg.user).size(20).text_align(Align::LEFT); ( image(include_bytes!("./assets/sungals.png")) .sized((70, 70)) .align(Align::TOP), (header, content) .span(Dir::DOWN) .gap(10) .width(rest(1)) .align(Align::TOP), ) .span(Dir::RIGHT) .gap(10) } pub fn focus(id: WidgetId, client: &mut Client, data: CursorData) { client.ui.text(&id).select(data.cursor, data.size); if let Some(region) = client.ui.window_region(&id) { client.handle.window.set_ime_allowed(true); client.handle.window.set_ime_cursor_area( LogicalPosition::::from(region.top_left.tuple()), LogicalSize::::from(region.size().tuple()), ); } client.focus = Some(id); } pub fn focus_other(id: WidgetId) -> impl Fn(&mut Client, CursorData) { move |client: &mut Client, data: CursorData| { focus(id.clone(), client, data); } } pub fn msg_panel(client: &mut Client, network: NetSender) -> impl WidgetFn + use<> { let Client { ui, channel, .. } = client; let msg_area = Span::empty(Dir::DOWN).gap(15).add(ui); *channel = Some(msg_area.clone()); let send_text = text("") .editable() .size(20) .wrap(true) .text_align(Align::TOP_LEFT) .add(ui); ( msg_area .clone() .scroll() .pad(Padding::x(15)) .height(rest(1)), send_text .clone() .id_on(Submit, move |id, client: &mut Client, _| { let content = client.ui.text(id).take(); let msg = Msg { content: content.clone(), user: client.username.clone(), }; network.send(ClientMsg::SendMsg(msg.clone())); let msg = msg_widget(msg).add(&mut client.ui); client.ui[&msg_area].children.push(msg.any()); }) .pad(15) .on(CursorSense::click(), focus_other(send_text)) .scroll() .masked() .background(rect(Color::BLACK.brighter(0.05)).radius(15)) .pad(15) .max_height(rel(0.5)) .z_offset(1), ) .span(Dir::DOWN) .width(rest(1)) // .background(rect(Color::BLACK.brighter(0.1))) }