From 1e82f4ff410ecddd7c5ed2f40943f84a03651fcc Mon Sep 17 00:00:00 2001 From: Imbris Date: Wed, 10 Jun 2020 01:08:08 -0400 Subject: [PATCH] Add border styling to container --- voxygen/src/menu/main/ui/connecting.rs | 10 +- voxygen/src/menu/main/ui/disclaimer.rs | 8 +- voxygen/src/menu/main/ui/mod.rs | 38 +++--- voxygen/src/menu/main/ui/servers.rs | 42 +++--- .../src/ui/ice/renderer/style/container.rs | 20 ++- .../src/ui/ice/renderer/widget/container.rs | 127 +++++++++++++++++- 6 files changed, 190 insertions(+), 55 deletions(-) diff --git a/voxygen/src/menu/main/ui/connecting.rs b/voxygen/src/menu/main/ui/connecting.rs index 36647f7d9c..7316ce3e47 100644 --- a/voxygen/src/menu/main/ui/connecting.rs +++ b/voxygen/src/menu/main/ui/connecting.rs @@ -6,7 +6,7 @@ use crate::{ ice::{component::neat_button, style, Element}, }, }; -use iced::{button, Align, Color, Column, Container, Length, Row, Space, Text, VerticalAlignment}; +use iced::{button, Align, Color, Column, Container, Length, Row, Space, Text}; /// Connecting screen for the main menu pub struct Screen { @@ -25,7 +25,6 @@ impl Screen { pub(super) fn view( &mut self, fonts: &Fonts, - imgs: &Imgs, connection_state: &ConnectionState, time: f32, i18n: &Localization, @@ -99,8 +98,11 @@ impl Screen { .height(Length::Fill); let prompt_window = Container::new(content) - // TODO: add borders - .style(style::container::Style::Color((10, 10, 0, 255).into())) + .style(style::container::Style::color_double_cornerless_border( + (22, 18, 16, 255).into(), + (11, 11, 11, 255).into(), + (54, 46, 38, 255).into(), + )) .padding(10); let container = Container::new(prompt_window) diff --git a/voxygen/src/menu/main/ui/disclaimer.rs b/voxygen/src/menu/main/ui/disclaimer.rs index ac5401772f..198544c012 100644 --- a/voxygen/src/menu/main/ui/disclaimer.rs +++ b/voxygen/src/menu/main/ui/disclaimer.rs @@ -7,7 +7,6 @@ use crate::{ }, }; use iced::{button, scrollable, Column, Container, Length, Scrollable, Space}; -use vek::Rgba; /// Connecting screen for the main menu pub struct Screen { @@ -26,7 +25,6 @@ impl Screen { pub(super) fn view( &mut self, fonts: &Fonts, - imgs: &Imgs, i18n: &Localization, button_style: style::button::Style, ) -> Element { @@ -66,7 +64,11 @@ impl Screen { .width(Length::Fill) .height(Length::Fill), ) - .style(style::container::Style::Color(Rgba::new(22, 19, 17, 255))), + .style(style::container::Style::color_double_cornerless_border( + (22, 19, 17, 255).into(), + (11, 11, 11, 255).into(), + (54, 46, 38, 255).into(), + )), ) .center_x() .center_y() diff --git a/voxygen/src/menu/main/ui/mod.rs b/voxygen/src/menu/main/ui/mod.rs index b9dd5171d1..2c660b8714 100644 --- a/voxygen/src/menu/main/ui/mod.rs +++ b/voxygen/src/menu/main/ui/mod.rs @@ -164,7 +164,6 @@ struct IcedState { // Voxygen version version: String, - servers: Vec, selected_server_index: Option, login_info: LoginInfo, @@ -219,13 +218,16 @@ impl IcedState { }; //}; - let servers = settings.networking.servers.clone(); let login_info = LoginInfo { username: settings.networking.username.clone(), password: String::new(), server: settings.networking.default_server.clone(), }; - let selected_server_index = servers.iter().position(|f| f == &login_info.server); + let selected_server_index = settings + .networking + .servers + .iter() + .position(|f| f == &login_info.server); Self { fonts, @@ -234,7 +236,6 @@ impl IcedState { i18n, version, - servers, selected_server_index, login_info, @@ -244,7 +245,7 @@ impl IcedState { } } - fn view(&mut self, dt: f32) -> Element { + fn view(&mut self, settings: &Settings, dt: f32) -> Element { self.time = self.time + dt; // TODO: consider setting this as the default in the renderer @@ -268,9 +269,7 @@ impl IcedState { // TODO: make any large text blocks scrollable so that if the area is to // small they can still be read let content = match &mut self.screen { - /*Screen::Disclaimer { screen } => { - screen.view(&self.fonts, &self.imgs, &self.i18n, button_style) - },*/ + //Screen::Disclaimer { screen } => screen.view(&self.fonts, &self.i18n, button_style), Screen::Login { screen, error } => screen.view( &self.fonts, &self.imgs, @@ -281,8 +280,7 @@ impl IcedState { ), Screen::Servers { screen } => screen.view( &self.fonts, - &self.imgs, - &self.servers, + &settings.networking.servers, self.selected_server_index, &self.i18n, button_style, @@ -292,7 +290,6 @@ impl IcedState { connection_state, } => screen.view( &self.fonts, - &self.imgs, &connection_state, self.time, &self.i18n, @@ -311,7 +308,9 @@ impl IcedState { .into() } - fn update(&mut self, message: Message, events: &mut Vec) { + fn update(&mut self, message: Message, events: &mut Vec, settings: &Settings) { + let servers = &settings.networking.servers; + match message { Message::Quit => events.push(Event::Quit), Message::Back => { @@ -321,6 +320,8 @@ impl IcedState { }; }, Message::ShowServers => { + self.selected_server_index = + servers.iter().position(|f| f == &self.login_info.server); self.screen = Screen::Servers { screen: servers::Screen::new(), }; @@ -353,12 +354,11 @@ impl IcedState { Message::Username(new_value) => self.login_info.username = new_value, Message::Password(new_value) => self.login_info.password = new_value, Message::Server(new_value) => { - self.selected_server_index = self.servers.iter().position(|f| f == &new_value); self.login_info.server = new_value; }, Message::ServerChanged(new_value) => { - self.login_info.server = self.servers[new_value].clone(); self.selected_server_index = Some(new_value); + self.login_info.server = servers[new_value].clone(); }, Message::FocusPassword => { if let Screen::Login { screen, .. } = &mut self.screen { @@ -1272,12 +1272,14 @@ impl<'a> MainMenuUi { self.ui.maintain(global_state.window.renderer_mut(), None); if self.show_iced { let (messages, _) = self.ice_ui.maintain( - self.ice_state.view(dt.as_secs_f32()), + self.ice_state + .view(&global_state.settings, dt.as_secs_f32()), global_state.window.renderer_mut(), ); - messages - .into_iter() - .for_each(|message| self.ice_state.update(message, &mut events)); + messages.into_iter().for_each(|message| { + self.ice_state + .update(message, &mut events, &global_state.settings) + }); } events diff --git a/voxygen/src/menu/main/ui/servers.rs b/voxygen/src/menu/main/ui/servers.rs index 817596a003..0443566a41 100644 --- a/voxygen/src/menu/main/ui/servers.rs +++ b/voxygen/src/menu/main/ui/servers.rs @@ -3,16 +3,7 @@ use crate::{ i18n::Localization, ui::{ fonts::IcedFonts as Fonts, - ice::{ - component::neat_button, - style, - widget::{ - background_container::Padding, - compound_graphic::{CompoundGraphic, Graphic}, - BackgroundContainer, - }, - Element, - }, + ice::{component::neat_button, style, Element}, }, }; use iced::{button, scrollable, Align, Button, Column, Container, Length, Scrollable, Text}; @@ -35,8 +26,7 @@ impl Screen { pub(super) fn view( &mut self, fonts: &Fonts, - imgs: &Imgs, - servers: &Vec, + servers: &[impl AsRef], selected_server_index: Option, i18n: &Localization, button_style: style::button::Style, @@ -56,38 +46,46 @@ impl Screen { let mut list = Scrollable::new(&mut self.servers_list) .align_items(Align::Start) .width(Length::Fill) - .height(Length::Fill) - .spacing(10); + .height(Length::Fill); if self.server_buttons.len() != servers.len() { self.server_buttons = vec![Default::default(); servers.len()]; } - for (i, state) in self.server_buttons.iter_mut().enumerate() { - let server = servers.get(i).unwrap(); + for (i, (state, server)) in self.server_buttons.iter_mut().zip(servers).enumerate() { let text = format!( "{}{}", - if i == selected_server_index.unwrap_or(std::usize::MAX) { + if Some(i) == selected_server_index { "-> " } else { " " }, - server + server.as_ref(), ); - let button = Button::new(state, Text::new(text).size(fonts.cyri.scale(25))) - .on_press(Message::ServerChanged(i)); + let button = Button::new( + state, + Container::new(Text::new(text).size(fonts.cyri.scale(25))) + .padding(5) + .center_y(), + ) + .width(Length::Fill) + .on_press(Message::ServerChanged(i)); list = list.push(button); } Container::new( - BackgroundContainer::new( - CompoundGraphic::padded_image(imgs.info_frame, [500, 300], [0; 4]), + Container::new( Column::with_children(vec![list.into(), button.into()]) .width(Length::Fill) .height(Length::Fill) .spacing(10) .padding(20), ) + .style(style::container::Style::color_double_cornerless_border( + (22, 18, 16, 255).into(), + (11, 11, 11, 255).into(), + (54, 46, 38, 255).into(), + )) .max_width(500), ) .width(Length::Fill) diff --git a/voxygen/src/ui/ice/renderer/style/container.rs b/voxygen/src/ui/ice/renderer/style/container.rs index c430a271bd..dde0865216 100644 --- a/voxygen/src/ui/ice/renderer/style/container.rs +++ b/voxygen/src/ui/ice/renderer/style/container.rs @@ -1,16 +1,34 @@ use super::super::super::widget::image; use vek::Rgba; +/// Container Border +pub enum Border { + DoubleCornerless { inner: Rgba, outer: Rgba }, + None, +} + /// Background of the container pub enum Style { Image(image::Handle, Rgba), - Color(Rgba), + Color(Rgba, Border), None, } impl Style { /// Shorthand for common case where the color of the image is not modified pub fn image(image: image::Handle) -> Self { Self::Image(image, Rgba::broadcast(255)) } + + /// Shorthand for a color background with no border + pub fn color(color: Rgba) -> Self { Self::Color(color, Border::None) } + + /// Shorthand for a color background with a cornerless border + pub fn color_double_cornerless_border( + color: Rgba, + inner: Rgba, + outer: Rgba, + ) -> Self { + Self::Color(color, Border::DoubleCornerless { inner, outer }) + } } impl Default for Style { diff --git a/voxygen/src/ui/ice/renderer/widget/container.rs b/voxygen/src/ui/ice/renderer/widget/container.rs index 4a30ede9a9..6b1559294f 100644 --- a/voxygen/src/ui/ice/renderer/widget/container.rs +++ b/voxygen/src/ui/ice/renderer/widget/container.rs @@ -1,6 +1,9 @@ use super::super::{super::Rotation, style, IcedRenderer, Primitive}; use common::util::srgba_to_linear; use iced::{container, Element, Layout, Point, Rectangle}; +use style::container::Border; + +const BORDER_SIZE: u16 = 8; impl container::Renderer for IcedRenderer { type Style = style::container::Style; @@ -29,15 +32,125 @@ impl container::Renderer for IcedRenderer { primitives: vec![background, content], } }, - Self::Style::Color(color) => { - let background = Primitive::Rectangle { - bounds, - linear_color: srgba_to_linear(color.map(|e| e as f32 / 255.0)), + Self::Style::Color(color, border) => { + let linear_color = srgba_to_linear(color.map(|e| e as f32 / 255.0)); + + let primitives = match border { + Border::None => { + let background = Primitive::Rectangle { + bounds, + linear_color, + }; + + vec![background, content] + }, + Border::DoubleCornerless { inner, outer } => { + let border_size = f32::from(BORDER_SIZE) + .min(bounds.width / 4.0) + .min(bounds.height / 4.0); + + let center = Primitive::Rectangle { + bounds: Rectangle { + x: bounds.x + border_size * 2.0, + y: bounds.y + border_size * 2.0, + width: bounds.width - border_size * 4.0, + height: bounds.height - border_size * 4.0, + }, + linear_color, + }; + + let linear_color = srgba_to_linear(outer.map(|e| e as f32 / 255.0)); + let top = Primitive::Rectangle { + bounds: Rectangle { + x: bounds.x + border_size, + y: bounds.y, + width: bounds.width - border_size * 2.0, + height: border_size, + }, + linear_color, + }; + let bottom = Primitive::Rectangle { + bounds: Rectangle { + x: bounds.x + border_size, + y: bounds.y + bounds.height - border_size, + width: bounds.width - border_size * 2.0, + height: border_size, + }, + linear_color, + }; + let left = Primitive::Rectangle { + bounds: Rectangle { + x: bounds.x, + y: bounds.y + border_size, + width: border_size, + height: bounds.height - border_size * 2.0, + }, + linear_color, + }; + let right = Primitive::Rectangle { + bounds: Rectangle { + x: bounds.x + bounds.width - border_size, + y: bounds.y + border_size, + width: border_size, + height: bounds.height - border_size * 2.0, + }, + linear_color, + }; + + let linear_color = srgba_to_linear(inner.map(|e| e as f32 / 255.0)); + let top_inner = Primitive::Rectangle { + bounds: Rectangle { + x: bounds.x + border_size, + y: bounds.y + border_size, + width: bounds.width - border_size * 2.0, + height: border_size, + }, + linear_color, + }; + let bottom_inner = Primitive::Rectangle { + bounds: Rectangle { + x: bounds.x + border_size, + y: bounds.y + bounds.height - border_size * 2.0, + width: bounds.width - border_size * 2.0, + height: border_size, + }, + linear_color, + }; + let left_inner = Primitive::Rectangle { + bounds: Rectangle { + x: bounds.x + border_size, + y: bounds.y + border_size * 2.0, + width: border_size, + height: bounds.height - border_size * 4.0, + }, + linear_color, + }; + let right_inner = Primitive::Rectangle { + bounds: Rectangle { + x: bounds.x + bounds.width - border_size * 2.0, + y: bounds.y + border_size * 2.0, + width: border_size, + height: bounds.height - border_size * 4.0, + }, + linear_color, + }; + + vec![ + center, + top, + bottom, + left, + right, + top_inner, + bottom_inner, + left_inner, + right_inner, + content, + ] + }, }; - Primitive::Group { - primitives: vec![background, content], - } + Primitive::Group { primitives } }, Self::Style::None => content, };