mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add Scrollable widget support, implement disclaimer screen, rearrangements of main menu ui code
This commit is contained in:
parent
01eb061a83
commit
e2bf974ecb
@ -255,7 +255,7 @@ impl PlayState for MainMenuState {
|
|||||||
},
|
},
|
||||||
MainMenuEvent::Settings => {}, // TODO
|
MainMenuEvent::Settings => {}, // TODO
|
||||||
MainMenuEvent::Quit => return PlayStateResult::Shutdown,
|
MainMenuEvent::Quit => return PlayStateResult::Shutdown,
|
||||||
/*MainMenuEvent::DisclaimerClosed => {
|
/*MainMenuEvent::DisclaimerAccepted => {
|
||||||
global_state.settings.show_disclaimer = false
|
global_state.settings.show_disclaimer = false
|
||||||
},*/
|
},*/
|
||||||
MainMenuEvent::AuthServerTrust(auth_server, trust) => {
|
MainMenuEvent::AuthServerTrust(auth_server, trust) => {
|
||||||
|
@ -3,12 +3,10 @@ use crate::{
|
|||||||
i18n::Localization,
|
i18n::Localization,
|
||||||
ui::{
|
ui::{
|
||||||
fonts::IcedFonts as Fonts,
|
fonts::IcedFonts as Fonts,
|
||||||
ice::{component::neat_button, style, widget::image, Element},
|
ice::{component::neat_button, style, Element},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use iced::{
|
use iced::{button, Align, Color, Column, Container, Length, Row, Space, Text, VerticalAlignment};
|
||||||
button, Align, Color, Column, Container, HorizontalAlignment, Length, Row, Space, Text,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Connecting screen for the main menu
|
/// Connecting screen for the main menu
|
||||||
pub struct Screen {
|
pub struct Screen {
|
||||||
@ -16,10 +14,6 @@ pub struct Screen {
|
|||||||
add_button: button::State,
|
add_button: button::State,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move to super and unify with identical login consts
|
|
||||||
const TEXT_COLOR: iced::Color = iced::Color::from_rgb(1.0, 1.0, 1.0);
|
|
||||||
const DISABLED_TEXT_COLOR: iced::Color = iced::Color::from_rgba(1.0, 1.0, 1.0, 0.2);
|
|
||||||
|
|
||||||
impl Screen {
|
impl Screen {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -32,32 +26,22 @@ impl Screen {
|
|||||||
&mut self,
|
&mut self,
|
||||||
fonts: &Fonts,
|
fonts: &Fonts,
|
||||||
imgs: &Imgs,
|
imgs: &Imgs,
|
||||||
bg_img: image::Handle,
|
|
||||||
connection_state: &ConnectionState,
|
connection_state: &ConnectionState,
|
||||||
version: &str,
|
|
||||||
time: f32,
|
time: f32,
|
||||||
i18n: &Localization,
|
i18n: &Localization,
|
||||||
|
button_style: style::button::Style,
|
||||||
) -> Element<Message> {
|
) -> Element<Message> {
|
||||||
let fade_msg = (time * 2.0).sin() * 0.5 + 0.51;
|
let fade_msg = (time * 2.0).sin() * 0.5 + 0.51;
|
||||||
let button_style = style::button::Style::new(imgs.button)
|
|
||||||
.hover_image(imgs.button_hover)
|
|
||||||
.press_image(imgs.button_press)
|
|
||||||
.text_color(TEXT_COLOR)
|
|
||||||
.disabled_text_color(DISABLED_TEXT_COLOR);
|
|
||||||
|
|
||||||
let version = Text::new(version)
|
let children = match connection_state {
|
||||||
.size(fonts.cyri.scale(15)) // move version text size to const
|
|
||||||
.width(Length::Fill)
|
|
||||||
.height(if matches!(connection_state, ConnectionState::InProgress {..}){Length::Fill}else{Length::Shrink})
|
|
||||||
.horizontal_alignment(HorizontalAlignment::Right);
|
|
||||||
|
|
||||||
let (middle, bottom) = match connection_state {
|
|
||||||
ConnectionState::InProgress { status } => {
|
ConnectionState::InProgress { status } => {
|
||||||
let status = Text::new(status)
|
let status = Text::new(status)
|
||||||
.size(fonts.alkhemi.scale(80))
|
.size(fonts.alkhemi.scale(80))
|
||||||
.font(fonts.alkhemi.id)
|
.font(fonts.alkhemi.id)
|
||||||
.color(Color::from_rgba(1.0, 1.0, 1.0, fade_msg))
|
.color(Color::from_rgba(1.0, 1.0, 1.0, fade_msg))
|
||||||
.width(Length::Fill);
|
.vertical_alignment(VerticalAlignment::Bottom)
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fill);
|
||||||
|
|
||||||
let status = Row::with_children(vec![
|
let status = Row::with_children(vec![
|
||||||
Space::new(Length::Units(80), Length::Shrink).into(),
|
Space::new(Length::Units(80), Length::Shrink).into(),
|
||||||
@ -78,7 +62,7 @@ impl Screen {
|
|||||||
.center_x()
|
.center_x()
|
||||||
.padding(3);
|
.padding(3);
|
||||||
|
|
||||||
(status.into(), cancel.into())
|
vec![status.into(), cancel.into()]
|
||||||
},
|
},
|
||||||
ConnectionState::AuthTrustPrompt { msg, .. } => {
|
ConnectionState::AuthTrustPrompt { msg, .. } => {
|
||||||
let text = Text::new(msg).size(fonts.cyri.scale(25));
|
let text = Text::new(msg).size(fonts.cyri.scale(25));
|
||||||
@ -125,22 +109,16 @@ impl Screen {
|
|||||||
.center_x()
|
.center_x()
|
||||||
.center_y();
|
.center_y();
|
||||||
|
|
||||||
(
|
vec![
|
||||||
container.into(),
|
container.into(),
|
||||||
Space::new(Length::Fill, Length::Units(fonts.cyri.scale(15))).into(),
|
Space::new(Length::Fill, Length::Units(fonts.cyri.scale(15))).into(),
|
||||||
)
|
]
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let content = Column::with_children(vec![version.into(), middle, bottom])
|
Column::with_children(children)
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
.padding(3);
|
|
||||||
|
|
||||||
// Note: could replace this with styling on iced's container since we aren't
|
|
||||||
// using fixed aspect ratio
|
|
||||||
Container::new(content)
|
|
||||||
.style(style::container::Style::image(bg_img))
|
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
78
voxygen/src/menu/main/ui/disclaimer.rs
Normal file
78
voxygen/src/menu/main/ui/disclaimer.rs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
use super::{IcedImgs as Imgs, Message};
|
||||||
|
use crate::{
|
||||||
|
i18n::Localization,
|
||||||
|
ui::{
|
||||||
|
fonts::IcedFonts as Fonts,
|
||||||
|
ice::{component::neat_button, style, Element},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use iced::{button, scrollable, Column, Container, Length, Scrollable, Space};
|
||||||
|
use vek::Rgba;
|
||||||
|
|
||||||
|
/// Connecting screen for the main menu
|
||||||
|
pub struct Screen {
|
||||||
|
accept_button: button::State,
|
||||||
|
scroll: scrollable::State,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Screen {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
accept_button: Default::default(),
|
||||||
|
scroll: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn view(
|
||||||
|
&mut self,
|
||||||
|
fonts: &Fonts,
|
||||||
|
imgs: &Imgs,
|
||||||
|
i18n: &Localization,
|
||||||
|
button_style: style::button::Style,
|
||||||
|
) -> Element<Message> {
|
||||||
|
Container::new(
|
||||||
|
Container::new(
|
||||||
|
Column::with_children(vec![
|
||||||
|
iced::Text::new(i18n.get("common.disclaimer"))
|
||||||
|
.font(fonts.alkhemi.id)
|
||||||
|
.size(fonts.alkhemi.scale(35))
|
||||||
|
.into(),
|
||||||
|
Space::new(Length::Fill, Length::Units(20)).into(),
|
||||||
|
Scrollable::new(&mut self.scroll)
|
||||||
|
.push(
|
||||||
|
iced::Text::new(i18n.get("main.notice"))
|
||||||
|
.font(fonts.cyri.id)
|
||||||
|
.size(fonts.cyri.scale(23)),
|
||||||
|
)
|
||||||
|
.height(Length::FillPortion(1))
|
||||||
|
.into(),
|
||||||
|
Container::new(
|
||||||
|
Container::new(neat_button(
|
||||||
|
&mut self.accept_button,
|
||||||
|
i18n.get("common.accept"),
|
||||||
|
0.7,
|
||||||
|
button_style,
|
||||||
|
Some(Message::AcceptDisclaimer),
|
||||||
|
))
|
||||||
|
.height(Length::Units(fonts.cyri.scale(50))),
|
||||||
|
)
|
||||||
|
.center_x()
|
||||||
|
.height(Length::Shrink)
|
||||||
|
.width(Length::Fill)
|
||||||
|
.into(),
|
||||||
|
])
|
||||||
|
.spacing(5)
|
||||||
|
.padding(20)
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fill),
|
||||||
|
)
|
||||||
|
.style(style::container::Style::Color(Rgba::new(22, 19, 17, 255))),
|
||||||
|
)
|
||||||
|
.center_x()
|
||||||
|
.center_y()
|
||||||
|
.padding(70)
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fill)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
use super::{IcedImgs as Imgs, Info, LoginInfo, Message};
|
use super::{IcedImgs as Imgs, LoginInfo, Message};
|
||||||
use crate::{
|
use crate::{
|
||||||
i18n::Localization,
|
i18n::Localization,
|
||||||
ui::{
|
ui::{
|
||||||
@ -14,14 +14,11 @@ use crate::{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use iced::{
|
use iced::{button, text_input, Align, Column, Container, Length, Row, Space, Text, TextInput};
|
||||||
button, text_input, Align, Column, Container, HorizontalAlignment, Length, Row, Space, Text,
|
|
||||||
TextInput,
|
|
||||||
};
|
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
const TEXT_COLOR: iced::Color = iced::Color::from_rgb(1.0, 1.0, 1.0);
|
pub const TEXT_COLOR: iced::Color = iced::Color::from_rgb(1.0, 1.0, 1.0);
|
||||||
const DISABLED_TEXT_COLOR: iced::Color = iced::Color::from_rgba(1.0, 1.0, 1.0, 0.2);
|
pub const DISABLED_TEXT_COLOR: iced::Color = iced::Color::from_rgba(1.0, 1.0, 1.0, 0.2);
|
||||||
const FILL_FRAC_ONE: f32 = 0.77;
|
const FILL_FRAC_ONE: f32 = 0.77;
|
||||||
const FILL_FRAC_TWO: f32 = 0.53;
|
const FILL_FRAC_TWO: f32 = 0.53;
|
||||||
const INPUT_WIDTH: u16 = 250;
|
const INPUT_WIDTH: u16 = 250;
|
||||||
@ -52,18 +49,11 @@ impl Screen {
|
|||||||
fonts: &Fonts,
|
fonts: &Fonts,
|
||||||
imgs: &Imgs,
|
imgs: &Imgs,
|
||||||
login_info: &LoginInfo,
|
login_info: &LoginInfo,
|
||||||
info: &Info,
|
|
||||||
error: Option<&str>,
|
error: Option<&str>,
|
||||||
version: &str,
|
|
||||||
show_servers: bool,
|
show_servers: bool,
|
||||||
i18n: &Localization,
|
i18n: &Localization,
|
||||||
|
button_style: style::button::Style,
|
||||||
) -> Element<Message> {
|
) -> Element<Message> {
|
||||||
let button_style = style::button::Style::new(imgs.button)
|
|
||||||
.hover_image(imgs.button_hover)
|
|
||||||
.press_image(imgs.button_press)
|
|
||||||
.text_color(TEXT_COLOR)
|
|
||||||
.disabled_text_color(DISABLED_TEXT_COLOR);
|
|
||||||
|
|
||||||
let buttons = Column::with_children(vec![
|
let buttons = Column::with_children(vec![
|
||||||
neat_button(
|
neat_button(
|
||||||
&mut self.servers_button,
|
&mut self.servers_button,
|
||||||
@ -96,32 +86,28 @@ impl Screen {
|
|||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
.align_y(Align::End);
|
.align_y(Align::End);
|
||||||
|
|
||||||
let left_column = if matches!(info, Info::Intro) {
|
let intro_text = i18n.get("main.login_process");
|
||||||
let intro_text = i18n.get("main.login_process");
|
|
||||||
|
|
||||||
let info_window = BackgroundContainer::new(
|
let info_window = BackgroundContainer::new(
|
||||||
CompoundGraphic::from_graphics(vec![
|
CompoundGraphic::from_graphics(vec![
|
||||||
Graphic::rect(Rgba::new(0, 0, 0, 240), [500, 300], [0, 0]),
|
Graphic::rect(Rgba::new(0, 0, 0, 240), [500, 300], [0, 0]),
|
||||||
// Note: a way to tell it to keep the height of this one piece constant and
|
// Note: a way to tell it to keep the height of this one piece constant and
|
||||||
// unstreched would be nice, I suppose we could just break this out into a
|
// unstreched would be nice, I suppose we could just break this out into a
|
||||||
// column and use Length::Units
|
// column and use Length::Units
|
||||||
Graphic::image(imgs.banner_bottom, [500, 30], [0, 300])
|
Graphic::image(imgs.banner_bottom, [500, 30], [0, 300])
|
||||||
.color(Rgba::new(255, 255, 255, 240)),
|
.color(Rgba::new(255, 255, 255, 240)),
|
||||||
])
|
])
|
||||||
.height(Length::Shrink),
|
.height(Length::Shrink),
|
||||||
Text::new(intro_text).size(fonts.cyri.scale(21)),
|
Text::new(intro_text).size(fonts.cyri.scale(21)),
|
||||||
)
|
)
|
||||||
.max_width(450)
|
.max_width(450)
|
||||||
.padding(Padding::new().horizontal(20).top(10).bottom(60));
|
.padding(Padding::new().horizontal(20).top(10).bottom(60));
|
||||||
|
|
||||||
Column::with_children(vec![info_window.into(), buttons.into()])
|
let left_column = Column::with_children(vec![info_window.into(), buttons.into()])
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
.padding(27)
|
.padding(27)
|
||||||
.into()
|
.into();
|
||||||
} else {
|
|
||||||
buttons.into()
|
|
||||||
};
|
|
||||||
|
|
||||||
let banner = self
|
let banner = self
|
||||||
.banner
|
.banner
|
||||||
@ -133,12 +119,9 @@ impl Screen {
|
|||||||
.align_x(Align::Center)
|
.align_x(Align::Center)
|
||||||
.align_y(Align::Center);
|
.align_y(Align::Center);
|
||||||
|
|
||||||
let right_column = Text::new(version)
|
let right_column = Space::new(Length::Fill, Length::Fill);
|
||||||
.size(fonts.cyri.scale(15))
|
|
||||||
.width(Length::Fill)
|
|
||||||
.horizontal_alignment(HorizontalAlignment::Right);
|
|
||||||
|
|
||||||
let content = Row::with_children(vec![
|
Row::with_children(vec![
|
||||||
left_column,
|
left_column,
|
||||||
central_column.into(),
|
central_column.into(),
|
||||||
right_column.into(),
|
right_column.into(),
|
||||||
@ -146,11 +129,7 @@ impl Screen {
|
|||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
.height(Length::Fill)
|
.height(Length::Fill)
|
||||||
.spacing(10)
|
.spacing(10)
|
||||||
.padding(3);
|
.into()
|
||||||
|
|
||||||
Container::new(content)
|
|
||||||
.style(style::container::Style::image(imgs.bg))
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
mod connecting;
|
mod connecting;
|
||||||
|
//mod disclaimer;
|
||||||
mod login;
|
mod login;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -34,7 +35,8 @@ const COL1: Color = Color::Rgba(0.07, 0.1, 0.1, 0.9);
|
|||||||
/*const UI_MAIN: Color = Color::Rgba(0.61, 0.70, 0.70, 1.0); // Greenish Blue
|
/*const UI_MAIN: Color = Color::Rgba(0.61, 0.70, 0.70, 1.0); // Greenish Blue
|
||||||
const UI_HIGHLIGHT_0: Color = Color::Rgba(0.79, 1.09, 1.09, 1.0);*/
|
const UI_HIGHLIGHT_0: Color = Color::Rgba(0.79, 1.09, 1.09, 1.0);*/
|
||||||
|
|
||||||
use iced::text_input;
|
use iced::{text_input, Column, Container, HorizontalAlignment, Length};
|
||||||
|
use ui::ice::style;
|
||||||
image_ids_ice! {
|
image_ids_ice! {
|
||||||
struct IcedImgs {
|
struct IcedImgs {
|
||||||
<VoxelGraphic>
|
<VoxelGraphic>
|
||||||
@ -94,6 +96,7 @@ pub enum Event {
|
|||||||
Quit,
|
Quit,
|
||||||
Settings,
|
Settings,
|
||||||
//DisclaimerClosed, TODO: remove all traces?
|
//DisclaimerClosed, TODO: remove all traces?
|
||||||
|
//DisclaimerAccepted,
|
||||||
AuthServerTrust(String, bool),
|
AuthServerTrust(String, bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,11 +117,6 @@ pub struct LoginInfo {
|
|||||||
pub server: String,
|
pub server: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Info {
|
|
||||||
//Disclaimer,
|
|
||||||
Intro,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ConnectionState {
|
enum ConnectionState {
|
||||||
InProgress {
|
InProgress {
|
||||||
status: String,
|
status: String,
|
||||||
@ -140,6 +138,9 @@ impl ConnectionState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum Screen {
|
enum Screen {
|
||||||
|
/*Disclaimer {
|
||||||
|
screen: disclaimer::Screen,
|
||||||
|
},*/
|
||||||
Login {
|
Login {
|
||||||
screen: login::Screen,
|
screen: login::Screen,
|
||||||
// Error to display in a box
|
// Error to display in a box
|
||||||
@ -162,7 +163,6 @@ struct IcedState {
|
|||||||
login_info: LoginInfo,
|
login_info: LoginInfo,
|
||||||
|
|
||||||
show_servers: bool,
|
show_servers: bool,
|
||||||
info: Info,
|
|
||||||
time: f32,
|
time: f32,
|
||||||
|
|
||||||
screen: Screen,
|
screen: Screen,
|
||||||
@ -183,7 +183,8 @@ enum Message {
|
|||||||
TrustPromptAdd,
|
TrustPromptAdd,
|
||||||
TrustPromptCancel,
|
TrustPromptCancel,
|
||||||
CloseError,
|
CloseError,
|
||||||
//CloseDisclaimer,
|
/*CloseDisclaimer,
|
||||||
|
*AcceptDisclaimer, */
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IcedState {
|
impl IcedState {
|
||||||
@ -200,10 +201,15 @@ impl IcedState {
|
|||||||
common::util::GIT_VERSION.to_string()
|
common::util::GIT_VERSION.to_string()
|
||||||
);
|
);
|
||||||
|
|
||||||
let info = Info::Intro; // if settings.show_disclaimer {
|
let screen = /* if settings.show_disclaimer {
|
||||||
//Info::Disclaimer
|
Screen::Disclaimer {
|
||||||
//} else {
|
screen: disclaimer::Screen::new(),
|
||||||
//Info::Intro
|
}
|
||||||
|
} else { */
|
||||||
|
Screen::Login {
|
||||||
|
screen: login::Screen::new(),
|
||||||
|
error: None,
|
||||||
|
};
|
||||||
//};
|
//};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -220,30 +226,47 @@ impl IcedState {
|
|||||||
},
|
},
|
||||||
|
|
||||||
show_servers: false,
|
show_servers: false,
|
||||||
info,
|
|
||||||
time: 0.0,
|
time: 0.0,
|
||||||
|
|
||||||
screen: Screen::Login {
|
screen,
|
||||||
screen: login::Screen::new(),
|
|
||||||
error: None,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(&mut self, dt: f32) -> Element<Message> {
|
fn view(&mut self, dt: f32) -> Element<Message> {
|
||||||
self.time = self.time + dt;
|
self.time = self.time + dt;
|
||||||
|
|
||||||
// TODO: make disclaimer it's own screen?
|
// TODO: consider setting this as the default in the renderer
|
||||||
match &mut self.screen {
|
let button_style = style::button::Style::new(self.imgs.button)
|
||||||
|
.hover_image(self.imgs.button_hover)
|
||||||
|
.press_image(self.imgs.button_press)
|
||||||
|
.text_color(login::TEXT_COLOR)
|
||||||
|
.disabled_text_color(login::DISABLED_TEXT_COLOR);
|
||||||
|
|
||||||
|
let version = iced::Text::new(&self.version)
|
||||||
|
.size(self.fonts.cyri.scale(15))
|
||||||
|
.width(Length::Fill)
|
||||||
|
.horizontal_alignment(HorizontalAlignment::Right);
|
||||||
|
|
||||||
|
let bg_img = if matches!(&self.screen, Screen::Connecting {..}) {
|
||||||
|
self.bg_img
|
||||||
|
} else {
|
||||||
|
self.imgs.bg
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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::Login { screen, error } => screen.view(
|
Screen::Login { screen, error } => screen.view(
|
||||||
&self.fonts,
|
&self.fonts,
|
||||||
&self.imgs,
|
&self.imgs,
|
||||||
&self.login_info,
|
&self.login_info,
|
||||||
&self.info,
|
|
||||||
error.as_deref(),
|
error.as_deref(),
|
||||||
&self.version,
|
|
||||||
self.show_servers,
|
self.show_servers,
|
||||||
&self.i18n,
|
&self.i18n,
|
||||||
|
button_style,
|
||||||
),
|
),
|
||||||
Screen::Connecting {
|
Screen::Connecting {
|
||||||
screen,
|
screen,
|
||||||
@ -251,13 +274,22 @@ impl IcedState {
|
|||||||
} => screen.view(
|
} => screen.view(
|
||||||
&self.fonts,
|
&self.fonts,
|
||||||
&self.imgs,
|
&self.imgs,
|
||||||
self.bg_img,
|
|
||||||
&connection_state,
|
&connection_state,
|
||||||
&self.version,
|
|
||||||
self.time,
|
self.time,
|
||||||
&self.i18n,
|
&self.i18n,
|
||||||
|
button_style,
|
||||||
),
|
),
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Container::new(
|
||||||
|
Column::with_children(vec![version.into(), content])
|
||||||
|
.spacing(3)
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fill),
|
||||||
|
)
|
||||||
|
.style(style::container::Style::image(bg_img))
|
||||||
|
.padding(3)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, message: Message, events: &mut Vec<Event>) {
|
fn update(&mut self, message: Message, events: &mut Vec<Event>) {
|
||||||
@ -330,6 +362,15 @@ impl IcedState {
|
|||||||
//Message::CloseDisclaimer => {
|
//Message::CloseDisclaimer => {
|
||||||
// events.push(Event::DisclaimerClosed);
|
// events.push(Event::DisclaimerClosed);
|
||||||
//},
|
//},
|
||||||
|
/*Message::AcceptDisclaimer => {
|
||||||
|
if let Screen::Disclaimer { .. } = &self.screen {
|
||||||
|
events.push(Event::DisclaimerAccepted);
|
||||||
|
self.screen = Screen::Login {
|
||||||
|
screen: login::Screen::new(),
|
||||||
|
error: None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -816,7 +857,7 @@ impl<'a> MainMenuUi {
|
|||||||
.was_clicked()
|
.was_clicked()
|
||||||
{
|
{
|
||||||
self.show_disclaimer = false;
|
self.show_disclaimer = false;
|
||||||
events.push(Event::DisclaimerClosed);
|
events.push(Event::DisclaimerAccepted);
|
||||||
}
|
}
|
||||||
} else {*/
|
} else {*/
|
||||||
// TODO: Don't use macros for this?
|
// TODO: Don't use macros for this?
|
||||||
|
@ -63,6 +63,8 @@ impl IcedUi {
|
|||||||
use iced::window;
|
use iced::window;
|
||||||
match event {
|
match event {
|
||||||
// Intercept resizing events
|
// Intercept resizing events
|
||||||
|
// TODO: examine if we are handling dpi properly here
|
||||||
|
// ideally these values should be the logical ones
|
||||||
Event::Window(window::Event::Resized { width, height }) => {
|
Event::Window(window::Event::Resized { width, height }) => {
|
||||||
self.window_resized = Some(Vec2::new(width, height));
|
self.window_resized = Some(Vec2::new(width, height));
|
||||||
},
|
},
|
||||||
|
@ -86,7 +86,7 @@ pub struct IcedRenderer {
|
|||||||
// Per-frame/update
|
// Per-frame/update
|
||||||
current_state: State,
|
current_state: State,
|
||||||
mesh: Mesh<UiPipeline>,
|
mesh: Mesh<UiPipeline>,
|
||||||
glyphs: Vec<(usize, usize, Rgba<f32>)>,
|
glyphs: Vec<(usize, usize, Rgba<f32>, Vec2<u32>)>,
|
||||||
// Output from glyph_brush in the previous frame
|
// Output from glyph_brush in the previous frame
|
||||||
// It can sometimes ask you to redraw with these instead (idk if that is done with
|
// It can sometimes ask you to redraw with these instead (idk if that is done with
|
||||||
// pre-positioned glyphs)
|
// pre-positioned glyphs)
|
||||||
@ -164,7 +164,7 @@ impl IcedRenderer {
|
|||||||
|
|
||||||
//self.current_scissor = default_scissor(renderer);
|
//self.current_scissor = default_scissor(renderer);
|
||||||
|
|
||||||
self.draw_primitive(primitive, renderer);
|
self.draw_primitive(primitive, Vec2::zero(), renderer);
|
||||||
|
|
||||||
// Enter the final command.
|
// Enter the final command.
|
||||||
self.draw_commands.push(match self.current_state {
|
self.draw_commands.push(match self.current_state {
|
||||||
@ -240,19 +240,29 @@ impl IcedRenderer {
|
|||||||
|
|
||||||
let glyphs = &self.glyphs;
|
let glyphs = &self.glyphs;
|
||||||
let mesh = &mut self.mesh;
|
let mesh = &mut self.mesh;
|
||||||
|
let p_scale = self.p_scale;
|
||||||
|
let half_res = self.half_res;
|
||||||
|
|
||||||
glyphs
|
glyphs
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|(mesh_index, glyph_count, linear_color)| {
|
.flat_map(|(mesh_index, glyph_count, linear_color, offset)| {
|
||||||
let mesh_index = *mesh_index;
|
let mesh_index = *mesh_index;
|
||||||
let linear_color = *linear_color;
|
let linear_color = *linear_color;
|
||||||
(0..*glyph_count).map(move |i| (mesh_index + i * 6, linear_color))
|
// Could potentially pass this in as part of the extras
|
||||||
|
let offset = offset.map(|e| e as f32 * p_scale) / half_res;
|
||||||
|
(0..*glyph_count).map(move |i| (mesh_index + i * 6, linear_color, offset))
|
||||||
})
|
})
|
||||||
.zip(self.last_glyph_verts.iter())
|
.zip(self.last_glyph_verts.iter())
|
||||||
.for_each(|((mesh_index, linear_color), (uv, rect))| {
|
.for_each(|((mesh_index, linear_color, offset), (uv, rect))| {
|
||||||
|
// TODO: add function to vek for this
|
||||||
|
let rect = Aabr {
|
||||||
|
min: rect.min + offset,
|
||||||
|
max: rect.max + offset,
|
||||||
|
};
|
||||||
|
|
||||||
mesh.replace_quad(
|
mesh.replace_quad(
|
||||||
mesh_index,
|
mesh_index,
|
||||||
create_ui_quad(*rect, *uv, linear_color, UiMode::Text),
|
create_ui_quad(rect, *uv, linear_color, UiMode::Text),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -344,12 +354,12 @@ impl IcedRenderer {
|
|||||||
Aabr { min, max }
|
Aabr { min, max }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_primitive(&mut self, primitive: Primitive, renderer: &mut Renderer) {
|
fn draw_primitive(&mut self, primitive: Primitive, offset: Vec2<u32>, renderer: &mut Renderer) {
|
||||||
match primitive {
|
match primitive {
|
||||||
Primitive::Group { primitives } => {
|
Primitive::Group { primitives } => {
|
||||||
primitives
|
primitives
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.for_each(|p| self.draw_primitive(p, renderer));
|
.for_each(|p| self.draw_primitive(p, offset, renderer));
|
||||||
},
|
},
|
||||||
Primitive::Image {
|
Primitive::Image {
|
||||||
handle,
|
handle,
|
||||||
@ -363,7 +373,11 @@ impl IcedRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let (graphic_id, rotation) = handle;
|
let (graphic_id, rotation) = handle;
|
||||||
let gl_aabr = self.gl_aabr(bounds);
|
let gl_aabr = self.gl_aabr(iced::Rectangle {
|
||||||
|
x: bounds.x + offset.x as f32,
|
||||||
|
y: bounds.y + offset.y as f32,
|
||||||
|
..bounds
|
||||||
|
});
|
||||||
|
|
||||||
let graphic_cache = self.cache.graphic_cache_mut();
|
let graphic_cache = self.cache.graphic_cache_mut();
|
||||||
|
|
||||||
@ -435,8 +449,14 @@ impl IcedRenderer {
|
|||||||
|
|
||||||
self.switch_state(State::Plain);
|
self.switch_state(State::Plain);
|
||||||
|
|
||||||
|
let gl_aabr = self.gl_aabr(iced::Rectangle {
|
||||||
|
x: bounds.x + offset.x as f32,
|
||||||
|
y: bounds.y + offset.y as f32,
|
||||||
|
..bounds
|
||||||
|
});
|
||||||
|
|
||||||
self.mesh.push_quad(create_ui_quad(
|
self.mesh.push_quad(create_ui_quad(
|
||||||
self.gl_aabr(bounds),
|
gl_aabr,
|
||||||
Aabr {
|
Aabr {
|
||||||
min: Vec2::zero(),
|
min: Vec2::zero(),
|
||||||
max: Vec2::zero(),
|
max: Vec2::zero(),
|
||||||
@ -470,7 +490,7 @@ impl IcedRenderer {
|
|||||||
// Since we already passed in `bounds` to position the glyphs some of this
|
// Since we already passed in `bounds` to position the glyphs some of this
|
||||||
// seems redundant...
|
// seems redundant...
|
||||||
// Note: we can't actually use this because dropping glyphs messeses up the
|
// Note: we can't actually use this because dropping glyphs messeses up the
|
||||||
// counting and there is not a convenient method provided to drop out of bounds
|
// counting and there is not a method provided to drop out of bounds
|
||||||
// glyphs while positioning them
|
// glyphs while positioning them
|
||||||
glyph_brush::ab_glyph::Rect {
|
glyph_brush::ab_glyph::Rect {
|
||||||
min: glyph_brush::ab_glyph::point(
|
min: glyph_brush::ab_glyph::point(
|
||||||
@ -489,8 +509,12 @@ impl IcedRenderer {
|
|||||||
min: Vec2::broadcast(0.0),
|
min: Vec2::broadcast(0.0),
|
||||||
max: Vec2::broadcast(0.0),
|
max: Vec2::broadcast(0.0),
|
||||||
};
|
};
|
||||||
self.glyphs
|
self.glyphs.push((
|
||||||
.push((self.mesh.vertices().len(), glyph_count, linear_color));
|
self.mesh.vertices().len(),
|
||||||
|
glyph_count,
|
||||||
|
linear_color,
|
||||||
|
offset,
|
||||||
|
));
|
||||||
for _ in 0..glyph_count {
|
for _ in 0..glyph_count {
|
||||||
// Push placeholder quad
|
// Push placeholder quad
|
||||||
// Note: moving to some sort of layering / z based system would be an
|
// Note: moving to some sort of layering / z based system would be an
|
||||||
@ -504,8 +528,13 @@ impl IcedRenderer {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Primitive::Clip { bounds, content } => {
|
Primitive::Clip {
|
||||||
|
bounds,
|
||||||
|
offset: clip_offset,
|
||||||
|
content,
|
||||||
|
} => {
|
||||||
let new_scissor = {
|
let new_scissor = {
|
||||||
|
// TODO: incorporate current offset for nested Clips
|
||||||
let intersection = Aabr {
|
let intersection = Aabr {
|
||||||
min: Vec2 {
|
min: Vec2 {
|
||||||
x: (bounds.x * self.p_scale) as u16,
|
x: (bounds.x * self.p_scale) as u16,
|
||||||
@ -545,7 +574,7 @@ impl IcedRenderer {
|
|||||||
// TODO: cull primitives outside the current scissor
|
// TODO: cull primitives outside the current scissor
|
||||||
|
|
||||||
// Renderer child
|
// Renderer child
|
||||||
self.draw_primitive(*content, renderer);
|
self.draw_primitive(*content, offset + clip_offset, renderer);
|
||||||
|
|
||||||
// Reset scissor
|
// Reset scissor
|
||||||
self.draw_commands.push(match self.current_state {
|
self.draw_commands.push(match self.current_state {
|
||||||
|
@ -25,6 +25,7 @@ pub enum Primitive {
|
|||||||
},
|
},
|
||||||
Clip {
|
Clip {
|
||||||
bounds: iced::Rectangle,
|
bounds: iced::Rectangle,
|
||||||
|
offset: vek::Vec2<u32>,
|
||||||
content: Box<Primitive>,
|
content: Box<Primitive>,
|
||||||
},
|
},
|
||||||
Nothing,
|
Nothing,
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
pub mod button;
|
pub mod button;
|
||||||
pub mod container;
|
pub mod container;
|
||||||
|
pub mod scrollable;
|
||||||
|
33
voxygen/src/ui/ice/renderer/style/scrollable.rs
Normal file
33
voxygen/src/ui/ice/renderer/style/scrollable.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use super::super::super::widget::image;
|
||||||
|
use vek::Rgba;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct Style {
|
||||||
|
pub track: Option<Track>,
|
||||||
|
pub scroller: Scroller,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Style {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
track: None,
|
||||||
|
scroller: Scroller::Color(Rgba::new(128, 128, 128, 255)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub enum Track {
|
||||||
|
Color(Rgba<u8>),
|
||||||
|
Image(image::Handle, Rgba<u8>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub enum Scroller {
|
||||||
|
Color(Rgba<u8>),
|
||||||
|
Image {
|
||||||
|
ends: image::Handle,
|
||||||
|
mid: image::Handle,
|
||||||
|
color: Rgba<u8>,
|
||||||
|
},
|
||||||
|
}
|
@ -6,6 +6,7 @@ mod compound_graphic;
|
|||||||
mod container;
|
mod container;
|
||||||
mod image;
|
mod image;
|
||||||
mod row;
|
mod row;
|
||||||
|
mod scrollable;
|
||||||
mod space;
|
mod space;
|
||||||
mod text;
|
mod text;
|
||||||
mod text_input;
|
mod text_input;
|
||||||
|
178
voxygen/src/ui/ice/renderer/widget/scrollable.rs
Normal file
178
voxygen/src/ui/ice/renderer/widget/scrollable.rs
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
use super::super::{super::Rotation, style, IcedRenderer, Primitive};
|
||||||
|
use common::util::srgba_to_linear;
|
||||||
|
use iced::{mouse, scrollable, Rectangle};
|
||||||
|
use style::scrollable::{Scroller, Track};
|
||||||
|
|
||||||
|
const SCROLLBAR_WIDTH: u16 = 10;
|
||||||
|
const SCROLLBAR_MIN_HEIGHT: u16 = 6;
|
||||||
|
const SCROLLBAR_MARGIN: u16 = 2;
|
||||||
|
|
||||||
|
impl scrollable::Renderer for IcedRenderer {
|
||||||
|
type Style = style::scrollable::Style;
|
||||||
|
|
||||||
|
// Interesting that this is here
|
||||||
|
// I guess we can take advantage of this to keep a constant size despite
|
||||||
|
// scaling?
|
||||||
|
fn scrollbar(
|
||||||
|
&self,
|
||||||
|
bounds: Rectangle,
|
||||||
|
content_bounds: Rectangle,
|
||||||
|
offset: u32,
|
||||||
|
) -> Option<scrollable::Scrollbar> {
|
||||||
|
// TODO: might actually want to divide by p_scale here (same in text&ext_input)
|
||||||
|
// (or just not use it) (or at least only account for dpi but not any
|
||||||
|
// additional scaling)
|
||||||
|
let width = (SCROLLBAR_WIDTH + 2 * SCROLLBAR_MARGIN) as f32 * self.p_scale;
|
||||||
|
if content_bounds.height > bounds.height {
|
||||||
|
let scrollbar_bounds = Rectangle {
|
||||||
|
x: bounds.x + bounds.width - width,
|
||||||
|
width,
|
||||||
|
..bounds
|
||||||
|
};
|
||||||
|
|
||||||
|
let visible_fraction = bounds.height / content_bounds.height;
|
||||||
|
let scrollbar_height = (bounds.height * visible_fraction)
|
||||||
|
.max((2 * SCROLLBAR_MIN_HEIGHT) as f32 * self.p_scale);
|
||||||
|
let y_offset = offset as f32 * visible_fraction;
|
||||||
|
|
||||||
|
let scroller_bounds = Rectangle {
|
||||||
|
x: scrollbar_bounds.x + SCROLLBAR_MARGIN as f32 * self.p_scale,
|
||||||
|
// TODO: check this behavior
|
||||||
|
y: scrollbar_bounds.y + y_offset,
|
||||||
|
width: scrollbar_bounds.width - (2 * SCROLLBAR_MARGIN) as f32 * self.p_scale,
|
||||||
|
height: scrollbar_height,
|
||||||
|
};
|
||||||
|
Some(scrollable::Scrollbar {
|
||||||
|
bounds: scrollbar_bounds,
|
||||||
|
scroller: scrollable::Scroller {
|
||||||
|
bounds: scroller_bounds,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(
|
||||||
|
&mut self,
|
||||||
|
state: &scrollable::State,
|
||||||
|
bounds: Rectangle,
|
||||||
|
_content_bounds: Rectangle,
|
||||||
|
is_mouse_over: bool,
|
||||||
|
is_mouse_over_scrollbar: bool,
|
||||||
|
scrollbar: Option<scrollable::Scrollbar>,
|
||||||
|
offset: u32,
|
||||||
|
style_sheet: &Self::Style,
|
||||||
|
(content, mouse_interaction): Self::Output,
|
||||||
|
) -> Self::Output {
|
||||||
|
(
|
||||||
|
if let Some(scrollbar) = scrollbar {
|
||||||
|
let mut primitives = Vec::with_capacity(5);
|
||||||
|
|
||||||
|
// Scrolled content
|
||||||
|
primitives.push(Primitive::Clip {
|
||||||
|
bounds,
|
||||||
|
offset: (0, offset).into(),
|
||||||
|
content: Box::new(content),
|
||||||
|
});
|
||||||
|
|
||||||
|
let style = style_sheet;
|
||||||
|
//let style = if state.is_scroller_grabbed() {
|
||||||
|
// style_sheet.dragging()
|
||||||
|
//} else if is_mouse_over_scrollbar {
|
||||||
|
// style_sheet.hovered()
|
||||||
|
//} else {
|
||||||
|
// style_sheet.active();
|
||||||
|
//};
|
||||||
|
|
||||||
|
let is_scrollbar_visible = style.track.is_some();
|
||||||
|
|
||||||
|
if is_mouse_over || state.is_scroller_grabbed() || is_scrollbar_visible {
|
||||||
|
let bounds = scrollbar.scroller.bounds;
|
||||||
|
|
||||||
|
match style.scroller {
|
||||||
|
Scroller::Color(color) => primitives.push(Primitive::Rectangle {
|
||||||
|
bounds,
|
||||||
|
linear_color: srgba_to_linear(color.map(|e| e as f32 / 255.0)),
|
||||||
|
}),
|
||||||
|
Scroller::Image { ends, mid, color } => {
|
||||||
|
// Calculate sizes of ends pieces based on image aspect ratio
|
||||||
|
let (img_w, img_h) = self.image_dims(ends);
|
||||||
|
let end_height = bounds.width * img_h as f32 / img_w as f32;
|
||||||
|
|
||||||
|
// Calcutate size of middle piece based on available space
|
||||||
|
// Note: Might want to scale into real pixels for parts of this
|
||||||
|
let (end_height, middle_height) =
|
||||||
|
if end_height * 2.0 + 1.0 <= bounds.height {
|
||||||
|
(end_height, bounds.height - end_height * 2.0)
|
||||||
|
} else {
|
||||||
|
// Take 1 logical pixel for the middle height
|
||||||
|
let remaining_height = bounds.height - 1.0;
|
||||||
|
(remaining_height / 2.0, 1.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Top
|
||||||
|
primitives.push(Primitive::Image {
|
||||||
|
handle: (ends, Rotation::None),
|
||||||
|
bounds: Rectangle {
|
||||||
|
height: end_height,
|
||||||
|
..bounds
|
||||||
|
},
|
||||||
|
color,
|
||||||
|
});
|
||||||
|
// Middle
|
||||||
|
primitives.push(Primitive::Image {
|
||||||
|
handle: (mid, Rotation::None),
|
||||||
|
bounds: Rectangle {
|
||||||
|
y: bounds.y + end_height,
|
||||||
|
height: middle_height,
|
||||||
|
..bounds
|
||||||
|
},
|
||||||
|
color,
|
||||||
|
});
|
||||||
|
// Bottom
|
||||||
|
primitives.push(Primitive::Image {
|
||||||
|
handle: (ends, Rotation::Cw180),
|
||||||
|
bounds: Rectangle {
|
||||||
|
y: bounds.y + end_height + middle_height,
|
||||||
|
height: end_height,
|
||||||
|
..bounds
|
||||||
|
},
|
||||||
|
color,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(track) = style.track {
|
||||||
|
let bounds = Rectangle {
|
||||||
|
x: scrollbar.bounds.x + SCROLLBAR_MARGIN as f32 * self.p_scale,
|
||||||
|
width: scrollbar.bounds.width
|
||||||
|
- (2 * SCROLLBAR_MARGIN) as f32 * self.p_scale,
|
||||||
|
..scrollbar.bounds
|
||||||
|
};
|
||||||
|
primitives.push(match track {
|
||||||
|
Track::Color(color) => Primitive::Rectangle {
|
||||||
|
bounds,
|
||||||
|
linear_color: srgba_to_linear(color.map(|e| e as f32 / 255.0)),
|
||||||
|
},
|
||||||
|
Track::Image(handle, color) => Primitive::Image {
|
||||||
|
handle: (handle, Rotation::None),
|
||||||
|
bounds,
|
||||||
|
color,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Primitive::Group { primitives }
|
||||||
|
} else {
|
||||||
|
content
|
||||||
|
},
|
||||||
|
if is_mouse_over_scrollbar || state.is_scroller_grabbed() {
|
||||||
|
mouse::Interaction::Idle
|
||||||
|
} else {
|
||||||
|
mouse_interaction
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -169,7 +169,7 @@ impl text_input::Renderer for IcedRenderer {
|
|||||||
(
|
(
|
||||||
Primitive::Rectangle {
|
Primitive::Rectangle {
|
||||||
bounds: Rectangle {
|
bounds: Rectangle {
|
||||||
x: text_bounds.x + position - offset - CURSOR_WIDTH / p_scale / 2.0,
|
x: text_bounds.x + position - CURSOR_WIDTH / p_scale / 2.0,
|
||||||
y: text_bounds.y,
|
y: text_bounds.y,
|
||||||
width: CURSOR_WIDTH / p_scale,
|
width: CURSOR_WIDTH / p_scale,
|
||||||
height: text_bounds.height,
|
height: text_bounds.height,
|
||||||
@ -196,7 +196,7 @@ impl text_input::Renderer for IcedRenderer {
|
|||||||
(
|
(
|
||||||
Primitive::Rectangle {
|
Primitive::Rectangle {
|
||||||
bounds: Rectangle {
|
bounds: Rectangle {
|
||||||
x: text_bounds.x + left_position - left_offset,
|
x: text_bounds.x + left_position,
|
||||||
y: text_bounds.y,
|
y: text_bounds.y,
|
||||||
width,
|
width,
|
||||||
height: text_bounds.height,
|
height: text_bounds.height,
|
||||||
@ -216,10 +216,9 @@ impl text_input::Renderer for IcedRenderer {
|
|||||||
|
|
||||||
let display_text = text.unwrap_or(if state.is_focused() { "" } else { placeholder });
|
let display_text = text.unwrap_or(if state.is_focused() { "" } else { placeholder });
|
||||||
let section = glyph_brush::Section {
|
let section = glyph_brush::Section {
|
||||||
screen_position: (
|
// Note: clip offset is an integer so we don't have to worry about not accounting for
|
||||||
text_bounds.x * p_scale - scroll_offset,
|
// that here where the alignment of the glyphs with pixels affects rasterization
|
||||||
text_bounds.center_y() * p_scale,
|
screen_position: (text_bounds.x * p_scale, text_bounds.center_y() * p_scale),
|
||||||
),
|
|
||||||
bounds: (
|
bounds: (
|
||||||
10000.0, /* text_bounds.width * p_scale */
|
10000.0, /* text_bounds.width * p_scale */
|
||||||
text_bounds.height * p_scale,
|
text_bounds.height * p_scale,
|
||||||
@ -279,9 +278,8 @@ impl text_input::Renderer for IcedRenderer {
|
|||||||
let primitive = if text_width > text_bounds.width {
|
let primitive = if text_width > text_bounds.width {
|
||||||
Primitive::Clip {
|
Primitive::Clip {
|
||||||
bounds: text_bounds,
|
bounds: text_bounds,
|
||||||
|
offset: (scroll_offset as u32, 0).into(),
|
||||||
content: Box::new(primitive),
|
content: Box::new(primitive),
|
||||||
/* Note: iced_wgpu uses offset here but we can't do that since we pass the text
|
|
||||||
* to the glyph_brush here */
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
primitive
|
primitive
|
||||||
|
Loading…
Reference in New Issue
Block a user