Add gradient primitive to ui, adjust textbox aspect ratio, misc tweaks

This commit is contained in:
Imbris 2020-06-27 16:30:43 -04:00
parent 3baac6aeba
commit 586bdddc9e
10 changed files with 108 additions and 46 deletions

BIN
assets/voxygen/element/frames/banner.png (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

View File

@ -19,7 +19,7 @@ use vek::*;
const FILL_FRAC_ONE: f32 = 0.77;
const FILL_FRAC_TWO: f32 = 0.53;
const INPUT_WIDTH: u16 = 250;
const INPUT_WIDTH: u16 = 280;
const INPUT_TEXT_SIZE: u16 = 24;
/// Login screen for the main menu
@ -95,8 +95,7 @@ impl Screen {
// 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
// column and use Length::Units
Graphic::image(imgs.banner_bottom, [500, 30], [0, 300])
.color(Rgba::new(255, 255, 255, 240)),
Graphic::gradient(Rgba::new(0, 0, 0, 240), Rgba::zero(), [500, 30], [0, 300]),
])
.height(Length::Shrink),
Text::new(intro_text).size(fonts.cyri.scale(21)),
@ -197,11 +196,10 @@ impl Banner {
let input_text_size = fonts.cyri.scale(INPUT_TEXT_SIZE);
let banner_content = Column::with_children(vec![
Image::new(imgs.v_logo)
.fix_aspect_ratio()
.height(Length::FillPortion(20))
Container::new(Image::new(imgs.v_logo).fix_aspect_ratio())
.padding(10)
.height(Length::FillPortion(25))
.into(),
Space::new(Length::Fill, Length::FillPortion(5)).into(),
Column::with_children(vec![
BackgroundContainer::new(
Image::new(imgs.input_bg)
@ -216,7 +214,7 @@ impl Banner {
.size(input_text_size)
.on_submit(Message::FocusPassword),
)
.padding(Padding::new().horizontal(10).top(10))
.padding(Padding::new().horizontal(7).top(5))
.into(),
BackgroundContainer::new(
Image::new(imgs.input_bg)
@ -232,7 +230,7 @@ impl Banner {
.password()
.on_submit(Message::Multiplayer),
)
.padding(Padding::new().horizontal(10).top(8))
.padding(Padding::new().horizontal(7).top(5))
.into(),
BackgroundContainer::new(
Image::new(imgs.input_bg)
@ -247,12 +245,13 @@ impl Banner {
.size(input_text_size)
.on_submit(Message::Multiplayer),
)
.padding(Padding::new().horizontal(10).top(8))
.padding(Padding::new().horizontal(7).top(5))
.into(),
])
.spacing(2)
.height(Length::FillPortion(50))
.spacing(10)
.height(Length::FillPortion(35))
.into(),
Space::new(Length::Fill, Length::FillPortion(2)).into(),
Column::with_children(vec![
neat_button(
&mut self.multiplayer_button,
@ -270,7 +269,8 @@ impl Banner {
Some(Message::Singleplayer),
),
])
.max_width(240)
.max_width(200)
.height(Length::FillPortion(38))
.spacing(8)
.into(),
])
@ -281,16 +281,16 @@ impl Banner {
let banner = BackgroundContainer::new(
CompoundGraphic::from_graphics(vec![
Graphic::image(imgs.banner_top, [138, 17], [0, 0]),
Graphic::rect(Rgba::new(0, 0, 0, 230), [130, 195], [4, 17]),
Graphic::image(imgs.banner, [130, 15], [4, 212])
.color(Rgba::new(255, 255, 255, 230)),
Graphic::rect(Rgba::new(0, 0, 0, 230), [130, 165], [4, 17]),
// TODO: use non image gradient
Graphic::gradient(Rgba::new(0, 0, 0, 230), Rgba::zero(), [130, 50], [4, 182]),
])
.fix_aspect_ratio()
.height(Length::Fill),
banner_content,
)
.padding(Padding::new().horizontal(16).vertical(20))
.max_width(330);
.padding(Padding::new().horizontal(8).vertical(15))
.max_width(350);
banner.into()
}

View File

@ -40,8 +40,6 @@ image_ids_ice! {
<ImageGraphic>
bg: "voxygen.background.bg_main",
banner: "voxygen.element.frames.banner",
banner_bottom: "voxygen.element.frames.banner_bottom",
banner_top: "voxygen.element.frames.banner_top",
button: "voxygen.element.buttons.button",
button_hover: "voxygen.element.buttons.button_hover",

View File

@ -31,8 +31,9 @@ pub use self::{
sprite::{Instance as SpriteInstance, Locals as SpriteLocals, SpritePipeline},
terrain::{Locals as TerrainLocals, TerrainPipeline},
ui::{
create_quad as create_ui_quad, create_tri as create_ui_tri, Locals as UiLocals,
Mode as UiMode, UiPipeline,
create_quad as create_ui_quad,
create_quad_vert_gradient as create_ui_quad_vert_gradient, create_tri as create_ui_tri,
Locals as UiLocals, Mode as UiMode, UiPipeline,
},
GlobalModel, Globals, Light, Shadow,
},

View File

@ -87,24 +87,37 @@ impl Mode {
}
}
#[allow(clippy::many_single_char_names)]
pub fn create_quad(
rect: Aabr<f32>,
uv_rect: Aabr<f32>,
color: Rgba<f32>,
mode: Mode,
) -> Quad<UiPipeline> {
create_quad_vert_gradient(rect, uv_rect, color, color, mode)
}
#[allow(clippy::many_single_char_names)]
pub fn create_quad_vert_gradient(
rect: Aabr<f32>,
uv_rect: Aabr<f32>,
top_color: Rgba<f32>,
bottom_color: Rgba<f32>,
mode: Mode,
) -> Quad<UiPipeline> {
let top_color = top_color.into_array();
let bottom_color = bottom_color.into_array();
let center = if let Mode::ImageSourceNorth = mode {
uv_rect.center().into_array()
} else {
rect.center().into_array()
};
let mode_val = mode.value();
let v = |pos, uv| Vertex {
let v = |pos, uv, color| Vertex {
pos,
uv,
center,
color: color.into_array(),
color,
mode: mode_val,
};
let aabr_to_lbrt = |aabr: Aabr<f32>| (aabr.min.x, aabr.min.y, aabr.max.x, aabr.max.y);
@ -114,22 +127,22 @@ pub fn create_quad(
match (uv_b > uv_t, uv_l > uv_r) {
(true, true) => Quad::new(
v([r, t], [uv_l, uv_b]),
v([l, t], [uv_l, uv_t]),
v([l, b], [uv_r, uv_t]),
v([r, b], [uv_r, uv_b]),
v([r, t], [uv_l, uv_b], top_color),
v([l, t], [uv_l, uv_t], top_color),
v([l, b], [uv_r, uv_t], bottom_color),
v([r, b], [uv_r, uv_b], bottom_color),
),
(false, false) => Quad::new(
v([r, t], [uv_l, uv_b]),
v([l, t], [uv_l, uv_t]),
v([l, b], [uv_r, uv_t]),
v([r, b], [uv_r, uv_b]),
v([r, t], [uv_l, uv_b], top_color),
v([l, t], [uv_l, uv_t], top_color),
v([l, b], [uv_r, uv_t], bottom_color),
v([r, b], [uv_r, uv_b], bottom_color),
),
_ => Quad::new(
v([r, t], [uv_r, uv_t]),
v([l, t], [uv_l, uv_t]),
v([l, b], [uv_l, uv_b]),
v([r, b], [uv_r, uv_b]),
v([r, t], [uv_r, uv_t], top_color),
v([l, t], [uv_l, uv_t], top_color),
v([l, b], [uv_l, uv_b], bottom_color),
v([r, b], [uv_r, uv_b], bottom_color),
),
}
}

View File

@ -15,7 +15,8 @@ use super::{
};
use crate::{
render::{
create_ui_quad, Consts, DynamicModel, Globals, Mesh, Renderer, UiLocals, UiMode, UiPipeline,
create_ui_quad, create_ui_quad_vert_gradient, Consts, DynamicModel, Globals, Mesh,
Renderer, UiLocals, UiMode, UiPipeline,
},
Error,
};
@ -454,6 +455,36 @@ impl IcedRenderer {
self.mesh
.push_quad(create_ui_quad(gl_aabr, uv_aabr, color, UiMode::Image));
},
Primitive::Gradient {
bounds,
top_linear_color,
bottom_linear_color,
} => {
// Don't draw a transparent rectangle.
if top_linear_color[3] == 0.0 && bottom_linear_color[3] == 0.0 {
return;
}
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_vert_gradient(
gl_aabr,
Aabr {
min: Vec2::zero(),
max: Vec2::zero(),
},
top_linear_color,
bottom_linear_color,
UiMode::Geometry,
));
},
Primitive::Rectangle {
bounds,
linear_color,

View File

@ -10,6 +10,13 @@ pub enum Primitive {
bounds: iced::Rectangle,
color: vek::Rgba<u8>,
},
// A vertical gradient
// TODO: could be combined with rectangle
Gradient {
bounds: iced::Rectangle,
top_linear_color: vek::Rgba<f32>,
bottom_linear_color: vek::Rgba<f32>,
},
Rectangle {
bounds: iced::Rectangle,
linear_color: vek::Rgba<f32>,

View File

@ -29,6 +29,13 @@ impl compound_graphic::Renderer for IcedRenderer {
bounds,
linear_color: srgba_to_linear(color.map(|e| e as f32 / 255.0)),
},
GraphicKind::Gradient(top_color, bottom_color) => Primitive::Gradient {
bounds,
top_linear_color: srgba_to_linear(top_color.map(|e| e as f32 / 255.0)),
bottom_linear_color: srgba_to_linear(
bottom_color.map(|e| e as f32 / 255.0),
),
},
})
.collect(),
},

View File

@ -11,9 +11,10 @@ use vek::{Aabr, Rgba, Vec2};
// TODO: design trait to interface with background container
#[derive(Copy, Clone)]
pub enum GraphicKind {
// TODO: if there is a use case, allow coloring individual images
Image(Handle, Rgba<u8>),
Color(Rgba<u8>),
/// Vertical gradient
Gradient(Rgba<u8>, Rgba<u8>),
}
// TODO: consider faculties for composing compound graphics (if a use case pops
@ -48,11 +49,21 @@ impl Graphic {
match &mut self.kind {
GraphicKind::Image(_, c) => *c = color,
GraphicKind::Color(c) => *c = color,
// Not relevant here
GraphicKind::Gradient(_, _) => (),
}
self
}
// TODO: consider removing color here
pub fn gradient(
top_color: Rgba<u8>,
bottom_color: Rgba<u8>,
size: [u16; 2],
offset: [u16; 2],
) -> Self {
Self::new(GraphicKind::Gradient(top_color, bottom_color), size, offset)
}
pub fn rect(color: Rgba<u8>, size: [u16; 2], offset: [u16; 2]) -> Self {
Self::new(GraphicKind::Color(color), size, offset)
}