update iris & get button working again

This commit is contained in:
2026-01-19 21:26:59 -05:00
parent 040b70e1c5
commit e67c55d67d
8 changed files with 213 additions and 70 deletions

View File

@@ -1,9 +1,10 @@
use crate::{Client, Rsc};
use iris::core::UiRenderState;
use openworm::net::NetServerMsg;
impl Client {
pub fn debug(&mut self, rsc: &mut Rsc) {
rsc.ui.debug_layers();
pub fn debug(&mut self, _rsc: &mut Rsc, render: &mut UiRenderState) {
render.debug_layers();
// let mut file = std::fs::OpenOptions::new()
// .write(true)
// .create(true)

View File

@@ -11,7 +11,10 @@ use openworm::{
net::{ClientMsg, ServerMsg, install_crypto_provider},
rsc::DataDir,
};
use winit::event::{ElementState, MouseButton, WindowEvent};
use winit::{
event::{ElementState, MouseButton, WindowEvent},
window::WindowAttributes,
};
mod account;
mod debug;
@@ -31,8 +34,8 @@ pub struct Client {
dir: DataDir,
data: ClientData,
state: ClientState,
main_ui: WidgetRef<WidgetPtr>,
notif: WidgetRef<WidgetPtr>,
main_ui: WeakWidget<WidgetPtr>,
notif: WeakWidget<WidgetPtr>,
proxy: Proxy<ClientEvent>,
}
@@ -48,7 +51,7 @@ impl DefaultAppState for Client {
type Event = ClientEvent;
fn new(
ui_state: DefaultUiState,
mut ui_state: DefaultUiState,
rsc: &mut DefaultRsc<Self>,
proxy: Proxy<Self::Event>,
) -> Self {
@@ -67,9 +70,9 @@ impl DefaultAppState for Client {
notif.pad(Padding::top(10)).align(Align::TOP_CENTER),
)
.stack()
.set_root(rsc);
.set_root(rsc, &mut ui_state);
main_view(rsc).set_ptr(main_ui, rsc);
start_ui(rsc).set_ptr(main_ui, rsc);
Self {
ui_state,
@@ -82,7 +85,12 @@ impl DefaultAppState for Client {
}
}
fn event(&mut self, event: Self::Event, rsc: &mut DefaultRsc<Self>) {
fn event(
&mut self,
event: Self::Event,
rsc: &mut DefaultRsc<Self>,
_render: &mut UiRenderState,
) {
match event {
ClientEvent::Connect { send } => {
let ClientState::Connect(connect) = self.state.take() else {
@@ -103,7 +111,7 @@ impl DefaultAppState for Client {
&& let Some(msg_area) = state.channel
{
let msg = msg_widget(&msg.user, &msg.content).add_strong(rsc);
rsc.ui[msg_area].children.push(msg);
rsc[msg_area].children.push(msg);
}
}
ServerMsg::LoadMsgs(msgs) => {
@@ -113,7 +121,7 @@ impl DefaultAppState for Client {
for msg in msgs {
state.msgs.push(msg.clone());
let msg = msg_widget(&msg.user, &msg.content).add_strong(rsc);
rsc.ui[msg_area].children.push(msg);
rsc[msg_area].children.push(msg);
}
}
}
@@ -132,28 +140,37 @@ impl DefaultAppState for Client {
}
ServerMsg::Error(error) => {
let msg = format!("{error:?}");
rsc.ui[self.notif].inner = Some(werror(&msg, rsc));
rsc[self.notif].inner = Some(werror(&msg, rsc));
}
},
ClientEvent::Err(msg) => {
rsc.ui[self.notif].inner = Some(werror(&msg, rsc));
rsc[self.notif].inner = Some(werror(&msg, rsc));
}
}
}
fn exit(&mut self, _: &mut DefaultRsc<Self>) {
fn exit(&mut self, _rsc: &mut DefaultRsc<Self>, _render: &mut UiRenderState) {
self.state.exit();
self.dir.save(CLIENT_DATA, &self.data);
}
fn window_event(&mut self, event: WindowEvent, rsc: &mut DefaultRsc<Self>) {
fn window_event(
&mut self,
event: WindowEvent,
rsc: &mut DefaultRsc<Self>,
render: &mut UiRenderState,
) {
if let WindowEvent::MouseInput {
state: ElementState::Pressed,
button: MouseButton::Middle,
..
} = event
{
self.debug(rsc);
self.debug(rsc, render);
}
}
fn window_attributes() -> WindowAttributes {
WindowAttributes::default().with_title("OPENWORM")
}
}

View File

@@ -15,7 +15,7 @@ pub struct Login {
pub struct LoggedIn {
pub network: NetHandle,
pub msgs: Vec<NetServerMsg>,
pub channel: Option<WidgetRef<Span>>,
pub channel: Option<WeakWidget<Span>>,
pub username: String,
}

View File

@@ -1,6 +1,6 @@
use super::*;
pub fn start_ui(rsc: &mut Rsc) -> WidgetRef {
pub fn start_ui(rsc: &mut Rsc) -> WeakWidget {
let mut accounts = Span::empty(Dir::DOWN);
accounts.push(
@@ -14,17 +14,15 @@ pub fn start_ui(rsc: &mut Rsc) -> WidgetRef {
let connect = Button::submit("connect", rsc);
let create = Button::submit("create", rsc);
connect.on(Submit, move |_, rsc| {
connect.disable();
create.disable();
rsc.events.register(connect.root(), Submit, move |_, rsc| {
connect.disable(rsc);
create.disable(rsc);
});
let connect_ = connect.clone();
let create_ = create.clone();
ui.on(create.view(), Submit, move |ctx| {
connect_.disable();
create_.disable();
create_ui(ctx.ui).set_ptr(&ctx.state.main_ui, ctx.ui);
rsc.events.register(create.root(), Submit, move |ctx, rsc| {
connect.disable(rsc);
create.disable(rsc);
create_ui(rsc).set_ptr(ctx.state.main_ui, rsc);
});
(
@@ -35,14 +33,14 @@ pub fn start_ui(rsc: &mut Rsc) -> WidgetRef {
.span(Dir::DOWN)
.gap(30)
.modal(400)
.add(ui)
.add(rsc)
}
pub fn create_ui(ui: &mut Ui) -> WidgetRef {
wtext("hi").add(ui)
pub fn create_ui(rsc: &mut Rsc) -> WeakWidget {
wtext("hi").add(rsc)
}
// pub fn connect_screen(client: &mut Client, ui: &mut Ui, state: &UiState) -> WidgetRef {
// pub fn connect_screen(client: &mut Client, ui: &mut Ui, state: &UiState) -> WeakWidget {
// let Client { data, proxy, .. } = client;
// let ip = field_widget(&data.ip, "ip", ui);
// let ip_ = ip.clone();
@@ -84,7 +82,7 @@ pub fn create_ui(ui: &mut Ui) -> WidgetRef {
// .add(ui)
// }
// pub fn login_screen(client: &mut Client, ui: &mut Ui) -> WidgetRef {
// pub fn login_screen(client: &mut Client, ui: &mut Ui) -> WeakWidget {
// let Client { data, .. } = client;
// let username = field_widget(&data.username, "username", ui);
// let password = field_widget(&data.password, "password", ui);

134
src/bin/client/ui/login.rs Normal file
View File

@@ -0,0 +1,134 @@
use iris::prelude::*;
use openworm::net::ClientMsg;
use crate::{net::AppHandle, state::ClientState};
use super::*;
pub fn start_screen(client: &mut Client, ui: &mut Ui) -> WidgetHandle {
let mut accounts = Span::empty(Dir::DOWN);
accounts.push(
wtext("no accounts")
.size(20)
.center_text()
.color(Color::GRAY)
.height(60)
.add(ui)
.any(),
);
(
wtext("Select Account").text_align(Align::CENTER).size(30),
accounts,
(
submit_button("connect", |_, _| {}),
submit_button("create", |_, _| {}),
)
.span(Dir::RIGHT)
.gap(10),
)
.span(Dir::DOWN)
.gap(10)
.pad(15)
.background(rect(Color::BLACK.brighter(0.2)).radius(15))
.width(400)
.align(Align::CENTER)
.add(ui)
.any()
}
pub fn connect_screen(client: &mut Client, ui: &mut Ui, state: &UiState) -> WidgetHandle {
let Client { data, proxy, .. } = client;
let ip = field_widget(&data.ip, "ip", ui);
let handle = AppHandle {
proxy: proxy.clone(),
window: state.window.clone(),
};
let submit = submit_button("connect", move |client, _ui| {
let ClientState::Connect(state) = &mut client.state else {
return;
};
let ip = ip_.get().content();
state.handle = Some(connect(handle.clone(), ConnectInfo { ip }));
});
(
wtext("connect to a server")
.text_align(Align::CENTER)
.size(30),
field_box(
// NOTE: should probably do this on submit
ip.on(Edited, |ctx| {
ctx.state.data.ip = ctx.widget.get().content();
})
.add(ui),
ui,
),
submit,
)
.span(Dir::DOWN)
.gap(10)
.pad(15)
.background(rect(Color::BLACK.brighter(0.2)).radius(15))
.width(400)
.align(Align::CENTER)
.add(ui)
.any()
}
pub fn login_screen(client: &mut Client, ui: &mut Ui) -> WidgetRef {
let Client { data, .. } = client;
let username = field_widget(&data.username, "username", ui);
let password = field_widget(&data.password, "password", ui);
let username_ = username.clone();
let password_ = password.clone();
let submit = submit_button("login", move |client, _ui| {
let ClientState::Login(state) = &mut client.state else {
return;
};
let username = username_.get().content();
let password = password_.get().content();
state.handle.send(ClientMsg::Login { username, password });
});
let username_ = username.clone();
let password_ = password.clone();
let create_button = submit_button("create account", move |client, _ui| {
let ClientState::Login(state) = &mut client.state else {
return;
};
let username = username_.get().content();
let password = password_.get().content();
state
.handle
.send(ClientMsg::CreateAccount { username, password });
});
(
wtext("login to server").text_align(Align::CENTER).size(30),
field_box(
username
.on(Edited, |ctx| {
ctx.state.data.username = ctx.widget.get().content();
})
.add(ui),
ui,
),
field_box(
password
.on(Edited, |ctx| {
ctx.state.data.password = ctx.widget.get().content();
})
.add(ui),
ui,
),
submit,
create_button,
)
.span(Dir::DOWN)
.gap(10)
.pad(15)
.background(rect(Color::BLACK.brighter(0.2)).radius(15))
.width(400)
.align(Align::CENTER)
.add(ui)
.any()
}

View File

@@ -4,7 +4,7 @@ use super::*;
pub const SIZE: u32 = 20;
pub fn main_view(rsc: &mut Rsc) -> WidgetRef {
pub fn main_view(rsc: &mut Rsc) -> WeakWidget {
let msg_panel = msg_panel(rsc);
let side_bar = rect(Color::BLACK.brighter(0.05)).width(80);
@@ -33,7 +33,7 @@ pub fn msg_widget(username: &str, content: &str) -> impl WidgetIdFn<Rsc> {
.to_any()
}
pub fn msg_panel(rsc: &mut Rsc) -> WidgetRef {
pub fn msg_panel(rsc: &mut Rsc) -> WeakWidget {
let msg_area = Span::empty(Dir::DOWN).gap(15);
let send_text = wtext("")
@@ -54,7 +54,7 @@ pub fn msg_panel(rsc: &mut Rsc) -> WidgetRef {
.on(Submit, move |ctx, rsc| {
let content = ctx.widget.edit(rsc).take();
let msg = msg_widget("ur mothe:", &content).add_strong(rsc);
rsc.ui[msg_area].children.push(msg);
rsc[msg_area].children.push(msg);
})
.pad(15)
.attr::<Selector>(send_text)

View File

@@ -1,6 +1,6 @@
use super::*;
pub fn werror(msg: &str, rsc: &mut Rsc) -> WidgetHandle {
pub fn werror(msg: &str, rsc: &mut Rsc) -> StrongWidget {
wtext(msg)
.size(20)
.pad(10)
@@ -12,7 +12,7 @@ pub fn hint(msg: impl Into<String>) -> TextBuilder<Rsc> {
wtext(msg).size(20).color(Color::GRAY)
}
pub fn field_widget(name: &str, hint_text: &str, rsc: &mut Rsc) -> WidgetRef<TextEdit> {
pub fn field_widget(name: &str, hint_text: &str, rsc: &mut Rsc) -> WeakWidget<TextEdit> {
wtext(name)
.editable(EditMode::SingleLine)
.size(20)
@@ -20,7 +20,7 @@ pub fn field_widget(name: &str, hint_text: &str, rsc: &mut Rsc) -> WidgetRef<Tex
.add(rsc)
}
pub fn field_box(field: WidgetRef<TextEdit>, rsc: &mut Rsc) -> WidgetRef {
pub fn field_box(field: WeakWidget<TextEdit>, rsc: &mut Rsc) -> WeakWidget {
field
.pad(10)
.background(rect(Color::BLACK.brighter(0.1)).radius(15))
@@ -31,55 +31,48 @@ pub fn field_box(field: WidgetRef<TextEdit>, rsc: &mut Rsc) -> WidgetRef {
#[derive(Clone, Copy, WidgetView)]
pub struct Button {
#[root]
root: WidgetRef,
rect: WidgetRef<Rect>,
enabled: Handle<bool>,
root: WeakWidget,
rect: WeakWidget<Rect>,
color: UiColor,
enabled: WeakState<bool>,
}
// impl WidgetView for Button {
// fn view(&self) -> &WidgetRef<Self::Widget> {
// &self.root
// }
// }
impl Button {
pub fn new(text: &str, color: UiColor, rsc: &mut Rsc) -> Self {
let rect = rect(color).radius(15).add(rsc);
// let enabled = Handle::from(true);
// let enabled_ = enabled.clone();
// let enabled__ = enabled.clone();
let enabled = rsc.create_state(rect, true);
let root = rect
.on(
CursorSense::HoverStart | CursorSense::unclick(),
move |ctx, rsc: &mut Rsc| {
// if !*enabled_.get() {
// return;
// }
rsc.ui[ctx.widget].color = color.brighter(0.1);
if !rsc[enabled] {
return;
}
rsc[ctx.widget].color = color.brighter(0.1);
},
)
.on(CursorSense::HoverEnd, move |ctx, rsc| {
// if !*enabled__.get() {
// return;
// }
rsc.ui[ctx.widget].color = color;
if !rsc[enabled] {
return;
}
rsc[ctx.widget].color = color;
})
.height(60)
.foreground(wtext(text).size(25).text_align(Align::CENTER))
.add(rsc);
// let enabled_ = enabled.clone();
rect.on(CursorSense::click(), move |ctx, rsc: &mut Rsc| {
// if !*enabled_.get() {
// return;
// }
rsc.ui[ctx.widget].color = color.darker(0.2);
if !rsc[enabled] {
return;
}
rsc[ctx.widget].color = color.darker(0.2);
rsc.run_event::<Submit>(root, (), ctx.state);
})
.add(rsc);
Self {
root,
rect,
// enabled,
color,
enabled,
}
}
@@ -88,21 +81,21 @@ impl Button {
}
pub fn disable(&self, rsc: &mut Rsc) {
*self.enabled.get_mut() = false;
self.rect.get_mut().color = self.color.darker(0.8);
rsc[self.enabled] = false;
rsc[self.rect].color = self.color.darker(0.8);
}
}
widget_trait! {
pub trait Stuff<Rsc: HasUi + 'static>;
pub trait Stuff<Rsc: UiRsc + 'static>;
fn modal(self, width: impl UiNum) -> impl WidgetIdFn<Rsc> {
|ui| {
|rsc| {
self
.pad(15)
.background(rect(color::MODAL_BG).radius(15))
.width(width)
.align(Align::CENTER)
.add(ui)
.add(rsc)
}
}
}