From acb5d4f8d5699f7ebf1883279b76aedfac001981 Mon Sep 17 00:00:00 2001 From: Alexey Date: Thu, 16 Dec 2021 09:04:10 +0300 Subject: [PATCH] Profile screen --- degeon/src/gui_events.rs | 2 ++ degeon/src/state.rs | 68 +++++++++++++++++++++++++++++++++++----- degeon/src/styles.rs | 15 ++++++--- 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/degeon/src/gui_events.rs b/degeon/src/gui_events.rs index b4bbfd4..6626307 100644 --- a/degeon/src/gui_events.rs +++ b/degeon/src/gui_events.rs @@ -19,6 +19,8 @@ pub enum GuiEvent { WeHaveToSendProfile(PublicKey), /// Go to another screen ChangeScreen(AppScreen), + /// Changed the name in the field on profile screen + ChangeName(String), /// Nothing happened None, } diff --git a/degeon/src/state.rs b/degeon/src/state.rs index 7787cfe..12919d3 100644 --- a/degeon/src/state.rs +++ b/degeon/src/state.rs @@ -4,12 +4,10 @@ use crate::gui_events::GuiEvent; use crate::message::{DegMessage, DegMessageContent, ProtocolMsg}; use crate::styles::style; use core::default::Default; -use iced::window::Mode; use iced::{ - button, Align, Application, Button, Color, Column, Element, HorizontalAlignment, Length, Row, - Settings, Text, TextInput, VerticalAlignment, + button, Align, Application, Button, Column, Element, HorizontalAlignment, Length, Row, + Text, TextInput, VerticalAlignment, }; -use ironforce::res::{IFError, IFResult}; use ironforce::PublicKey; /// Render a message into an iced `Element` @@ -49,6 +47,7 @@ pub enum AppScreen { /// Settings and profile ProfileEditor, /// The screen that appears if no peers are available and asks for the IP address of at least one peer + #[allow(dead_code)] PeerInput, } @@ -73,6 +72,10 @@ pub struct DegeonApp { text_input_state: iced::text_input::State, /// Buttons for chat previews preview_button_states: Vec, + /// Name input on profile screen + name_input_state: iced::text_input::State, + /// Button on the profile screen + profile_done_button_state: iced::button::State, } impl DegeonApp { @@ -145,6 +148,46 @@ impl DegeonApp { .height(Length::Fill) .into() } + + fn profile_editor(&mut self) -> Element { + let Self { + data: + Degeon { + profile: crate::message::Profile { name }, + .. + }, + profile_done_button_state, + name_input_state, + .. + } = self; + iced::Container::new( + Column::new() + .align_items(Align::Center) + .width(Length::Fill) + .spacing(60) + .push(Text::new("Profile")) + .push( + iced::Container::new(Row::with_children(vec![ + Text::new("Name").into(), + TextInput::new(name_input_state, "Name", name.as_str(), |name| { + GuiEvent::ChangeName(name) + }) + .padding(5) + .into(), + ]).max_width(250).align_items(Align::Center)) + .align_x(Align::Center) + .padding(40) + .style(style::Container::Field), + ) + .push( + Button::new(profile_done_button_state, Text::new("Done")) + .style(style::Button::Primary) + .on_press(GuiEvent::ChangeScreen(AppScreen::Main)), + ), + ) + .align_x(Align::Center) + .into() + } } impl Application for DegeonApp { @@ -155,15 +198,20 @@ impl Application for DegeonApp { fn new(_: ()) -> (Self, iced::Command) { let mut data = Degeon::restore_from_file("".to_string()).unwrap(); data.chats = vec![Chat::example(1, &data.keys), Chat::example(2, &data.keys)]; - data.profile.name = "John".to_string(); data.send_multicast(ProtocolMsg::Ping).unwrap(); let st = DegeonApp { + screen: if data.profile.name.is_empty() { + AppScreen::ProfileEditor + } else { + AppScreen::Main + }, data, - screen: Default::default(), selected_chat: 0, send_button_state: Default::default(), text_input_state: Default::default(), preview_button_states: vec![Default::default(), Default::default()], + name_input_state: Default::default(), + profile_done_button_state: Default::default(), }; let data_clone = st.data.clone(); std::thread::spawn(move || { @@ -229,7 +277,11 @@ impl Application for DegeonApp { &target, ); } - GuiEvent::ChangeScreen(sc) => self.screen = sc, + GuiEvent::ChangeScreen(sc) => { + self.screen = sc; + self.data.save_to_file("".to_string()).unwrap(); + } + GuiEvent::ChangeName(name) => self.data.profile.name = name, } iced::Command::none() } @@ -241,7 +293,7 @@ impl Application for DegeonApp { fn view(&mut self) -> Element<'_, Self::Message> { match self.screen { AppScreen::Main => self.main_view(), - AppScreen::ProfileEditor => todo!(), + AppScreen::ProfileEditor => self.profile_editor(), AppScreen::PeerInput => todo!(), } } diff --git a/degeon/src/styles.rs b/degeon/src/styles.rs index fd8cc7e..9f8aea7 100644 --- a/degeon/src/styles.rs +++ b/degeon/src/styles.rs @@ -1,6 +1,6 @@ pub mod style { use iced::container::Style; - use iced::{Background, button, Color, Vector}; + use iced::{button, Background, Color, Vector}; #[derive(Clone, Copy, PartialEq, Eq)] pub enum Button { @@ -32,24 +32,31 @@ pub mod style { } } + #[derive(Copy, Clone, PartialEq)] pub enum Container { Primary, MyMessage, NotMyMessage, + Field, } impl iced::container::StyleSheet for Container { fn style(&self) -> Style { iced::container::Style { - text_color: Some(Color::WHITE), + text_color: if *self != Container::Field { Some(Color::WHITE) } else { Some(Color::BLACK) }, background: Some(Background::Color(match self { Container::Primary => Color::from_rgb(18. / 256., 25. / 256., 70. / 256.), Container::MyMessage => Color::from_rgb(0., 0.1, 0.8), Container::NotMyMessage => Color::from_rgb(0., 0.1, 0.4), + Container::Field => Color::TRANSPARENT, })), border_radius: 5.0, - border_width: 0.6, - border_color: Color::TRANSPARENT, + border_width: 0.9, + border_color: if *self != Container::Field { + Color::TRANSPARENT + } else { + Color::BLACK + }, } } }