diff --git a/src/bin/client/ui.rs b/src/bin/client/ui.rs deleted file mode 100644 index be91f75..0000000 --- a/src/bin/client/ui.rs +++ /dev/null @@ -1,189 +0,0 @@ -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").text_align(Align::CENTER).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) - .wrap(true) - .id_on(CursorSense::click(), |i, c, d| focus(i.clone(), c, d)); - let header = text(msg.user).size(20); - ( - 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).add(ui); - - ( - msg_area - .clone() - .scroll() - .pad(Padding::x(15).with_top(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)) -} diff --git a/src/bin/client/ui/login.rs b/src/bin/client/ui/login.rs new file mode 100644 index 0000000..0909b98 --- /dev/null +++ b/src/bin/client/ui/login.rs @@ -0,0 +1,67 @@ +use super::*; + +pub fn login_screen(client: &mut Client) -> WidgetId { + let Client { + ui, handle, data, .. + } = client; + + let mut field = |name, hint_| { + text(name) + .editable() + .size(20) + .hint(hint(hint_)) + .add(ui) + }; + let ip = field(&data.ip, "ip"); + let username = field(&data.username, "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").text_align(Align::CENTER).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() +} diff --git a/src/bin/client/ui/main.rs b/src/bin/client/ui/main.rs new file mode 100644 index 0000000..9445515 --- /dev/null +++ b/src/bin/client/ui/main.rs @@ -0,0 +1,83 @@ +use super::*; + +pub const SIZE: u32 = 20; + +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 msg_widget(msg: Msg) -> impl WidgetLike { + let content = text(msg.content) + .editable() + .size(SIZE) + .wrap(true) + .id_on(CursorSense::click(), |i, c, d| focus(i.clone(), c, d)); + let header = text(msg.user).size(SIZE); + ( + 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 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(SIZE) + .wrap(true) + .hint(hint("send message")) + .add(ui); + + ( + msg_area + .clone() + .scroll() + .pad(Padding::x(15).with_top(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)) +} diff --git a/src/bin/client/ui/misc.rs b/src/bin/client/ui/misc.rs new file mode 100644 index 0000000..ea72654 --- /dev/null +++ b/src/bin/client/ui/misc.rs @@ -0,0 +1,33 @@ +use super::*; + +pub fn error(ui: &mut Ui, msg: &str) -> WidgetId { + text(msg) + .size(20) + .color(Color::RED.brighter(0.3)) + .pad(10) + .add(ui) + .any() +} + +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 hint(msg: impl Into) -> TextBuilder { + text(msg).size(20).color(Color::GRAY) +} + diff --git a/src/bin/client/ui/mod.rs b/src/bin/client/ui/mod.rs new file mode 100644 index 0000000..9be60ff --- /dev/null +++ b/src/bin/client/ui/mod.rs @@ -0,0 +1,33 @@ +use crate::{ + Client, + net::{ConnectInfo, NetSender, connect}, + ui::login::login_screen, +}; +use iris::prelude::*; +use len_fns::*; +use openworm::net::{ClientMsg, Msg}; +use winit::dpi::{LogicalPosition, LogicalSize}; + +mod login; +mod main; +mod misc; +pub use main::*; +pub use misc::*; + +#[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); +}