mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add support for Button widget, new custom widget AspectRatioContainer
This commit is contained in:
parent
bc0792a57a
commit
095345d8c6
@ -158,6 +158,7 @@ rotation_image_ids! {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)] // TODO: why does iced require Clone?
|
||||
pub enum Event {
|
||||
LoginAttempt {
|
||||
username: String,
|
||||
@ -187,26 +188,59 @@ pub struct PopupData {
|
||||
// No state currently
|
||||
struct IcedState {
|
||||
imgs: IcedImgs,
|
||||
quit_button: iced::button::State,
|
||||
}
|
||||
pub type Message = Event;
|
||||
impl IcedState {
|
||||
pub fn new(imgs: IcedImgs) -> Self {
|
||||
Self {
|
||||
imgs,
|
||||
quit_button: iced::button::State::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view(&mut self, i18n: &Localization) -> Element<Message> {
|
||||
use iced::{Align, Column, Container, Length, Row, Space, Text};
|
||||
// TODO: scale with window size
|
||||
let button_font_size = 30;
|
||||
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);
|
||||
|
||||
use iced::{
|
||||
Align, Button, Column, Container, HorizontalAlignment, Length, Row, Space, Text,
|
||||
VerticalAlignment,
|
||||
};
|
||||
use ui::ice::{
|
||||
compound_graphic::{CompoundGraphic, Graphic},
|
||||
BackgroundContainer, Image, Padding,
|
||||
AspectRatioContainer, BackgroundContainer, ButtonStyle, Image, Padding,
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
let button_style = ButtonStyle::new(self.imgs.button)
|
||||
.hover_image(self.imgs.button_hover)
|
||||
.press_image(self.imgs.button_press)
|
||||
.text_color(TEXT_COLOR)
|
||||
.disabled_text_color(DISABLED_TEXT_COLOR);
|
||||
|
||||
let buttons = Column::with_children(vec![
|
||||
Image::new(self.imgs.button).fix_aspect_ratio().into(),
|
||||
Image::new(self.imgs.button).fix_aspect_ratio().into(),
|
||||
/* BackgroundContainer::new(
|
||||
Image::new(self.imgs.button).fix_aspect_ratio(),
|
||||
Text::new("Quit"),
|
||||
AspectRatioContainer::new(
|
||||
Button::new(
|
||||
&mut self.quit_button,
|
||||
Text::new(i18n.get("common.quit"))
|
||||
.size(button_font_size)
|
||||
.height(Length::Fill)
|
||||
.width(Length::Fill)
|
||||
.horizontal_alignment(HorizontalAlignment::Center)
|
||||
.vertical_alignment(VerticalAlignment::Center),
|
||||
)
|
||||
.height(Length::Fill)
|
||||
.width(Length::Fill)
|
||||
.style(button_style)
|
||||
.on_press(Message::Quit),
|
||||
)
|
||||
.into(), */
|
||||
Text::new(i18n.get("common.quit")).size(40).into(),
|
||||
.ratio_of_image(self.imgs.button)
|
||||
.into(),
|
||||
])
|
||||
.width(Length::Fill)
|
||||
.max_width(200)
|
||||
@ -314,13 +348,7 @@ impl IcedState {
|
||||
.height(Length::Fill)
|
||||
.spacing(10);
|
||||
|
||||
BackgroundContainer::new(
|
||||
Image::new(self.imgs.bg)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill),
|
||||
content,
|
||||
)
|
||||
.into()
|
||||
BackgroundContainer::new(Image::new(self.imgs.bg), content).into()
|
||||
}
|
||||
|
||||
pub fn update(message: Message) {
|
||||
@ -413,9 +441,7 @@ impl<'a> MainMenuUi {
|
||||
};
|
||||
|
||||
let mut ice_ui = IcedUi::new(window, ice_font).unwrap();
|
||||
let ice_state = IcedState {
|
||||
imgs: IcedImgs::load(&mut ice_ui).expect("Failed to load images"),
|
||||
};
|
||||
let ice_state = IcedState::new(IcedImgs::load(&mut ice_ui).expect("Failed to load images"));
|
||||
|
||||
Self {
|
||||
ui,
|
||||
|
@ -8,8 +8,9 @@ mod winit_conversion;
|
||||
pub use cache::Font;
|
||||
pub use graphic::{Id, Rotation};
|
||||
pub use iced::Event;
|
||||
pub use renderer::IcedRenderer;
|
||||
pub use renderer::{ButtonStyle, IcedRenderer};
|
||||
pub use widget::{
|
||||
aspect_ratio_container::AspectRatioContainer,
|
||||
background_container::{BackgroundContainer, Padding},
|
||||
compound_graphic,
|
||||
image::Image,
|
||||
|
25
voxygen/src/ui/ice/renderer/aspect_ratio_container.rs
Normal file
25
voxygen/src/ui/ice/renderer/aspect_ratio_container.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use super::{
|
||||
super::widget::{aspect_ratio_container, image},
|
||||
IcedRenderer,
|
||||
};
|
||||
use iced::{Element, Layout, Point, Rectangle};
|
||||
|
||||
impl aspect_ratio_container::Renderer for IcedRenderer {
|
||||
//type Style
|
||||
type ImageHandle = image::Handle;
|
||||
|
||||
fn dimensions(&self, handle: &Self::ImageHandle) -> (u32, u32) { self.image_dims(*handle) }
|
||||
|
||||
fn draw<M>(
|
||||
&mut self,
|
||||
defaults: &Self::Defaults,
|
||||
_bounds: Rectangle,
|
||||
cursor_position: Point,
|
||||
//style: &Self::Style,
|
||||
content: &Element<'_, M, Self>,
|
||||
content_layout: Layout<'_>,
|
||||
) -> Self::Output {
|
||||
// TODO: stlying to add a background image and such
|
||||
content.draw(self, defaults, content_layout, cursor_position)
|
||||
}
|
||||
}
|
165
voxygen/src/ui/ice/renderer/button.rs
Normal file
165
voxygen/src/ui/ice/renderer/button.rs
Normal file
@ -0,0 +1,165 @@
|
||||
use super::{super::Rotation, widget::image, Defaults, IcedRenderer, Primitive};
|
||||
use iced::{button, mouse, Color, Element, Layout, Point, Rectangle};
|
||||
use vek::Rgba;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct Background {
|
||||
default: image::Handle,
|
||||
hover: image::Handle,
|
||||
press: image::Handle,
|
||||
}
|
||||
|
||||
impl Background {
|
||||
fn new(image: image::Handle) -> Self {
|
||||
Self {
|
||||
default: image,
|
||||
hover: image,
|
||||
press: image,
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: consider a different place for this
|
||||
// Note: for now all buttons have an image background
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Style {
|
||||
background: Option<Background>,
|
||||
enabled_text: Color,
|
||||
disabled_text: Color,
|
||||
/* greying out / changing text color
|
||||
*disabled: , */
|
||||
}
|
||||
|
||||
impl Style {
|
||||
pub fn new(image: image::Handle) -> Self {
|
||||
Self {
|
||||
background: Some(Background::new(image)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hover_image(mut self, image: image::Handle) -> Self {
|
||||
self.background = Some(match self.background {
|
||||
Some(mut background) => {
|
||||
background.hover = image;
|
||||
background
|
||||
},
|
||||
None => Background::new(image),
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
pub fn press_image(mut self, image: image::Handle) -> Self {
|
||||
self.background = Some(match self.background {
|
||||
Some(mut background) => {
|
||||
background.press = image;
|
||||
background
|
||||
},
|
||||
None => Background::new(image),
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
pub fn text_color(mut self, color: Color) -> Self {
|
||||
self.enabled_text = color;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn disabled_text_color(mut self, color: Color) -> Self {
|
||||
self.disabled_text = color;
|
||||
self
|
||||
}
|
||||
|
||||
fn disabled(&self) -> (Option<image::Handle>, Color) {
|
||||
(
|
||||
self.background.as_ref().map(|b| b.default),
|
||||
self.disabled_text,
|
||||
)
|
||||
}
|
||||
|
||||
fn pressed(&self) -> (Option<image::Handle>, Color) {
|
||||
(self.background.as_ref().map(|b| b.press), self.enabled_text)
|
||||
}
|
||||
|
||||
fn hovered(&self) -> (Option<image::Handle>, Color) {
|
||||
(self.background.as_ref().map(|b| b.hover), self.enabled_text)
|
||||
}
|
||||
|
||||
fn active(&self) -> (Option<image::Handle>, Color) {
|
||||
(
|
||||
self.background.as_ref().map(|b| b.default),
|
||||
self.enabled_text,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Style {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
background: None,
|
||||
enabled_text: Color::WHITE,
|
||||
disabled_text: Color::from_rgb(0.5, 0.5, 0.5),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl button::Renderer for IcedRenderer {
|
||||
// TODO: what if this gets large enough to not be copied around?
|
||||
type Style = Style;
|
||||
|
||||
const DEFAULT_PADDING: u16 = 0;
|
||||
|
||||
fn draw<M>(
|
||||
&mut self,
|
||||
defaults: &Self::Defaults,
|
||||
bounds: Rectangle,
|
||||
cursor_position: Point,
|
||||
is_disabled: bool,
|
||||
is_pressed: bool,
|
||||
style: &Self::Style,
|
||||
content: &Element<'_, M, Self>,
|
||||
content_layout: Layout<'_>,
|
||||
) -> Self::Output {
|
||||
let is_mouse_over = bounds.contains(cursor_position);
|
||||
|
||||
let (maybe_image, text_color) = if is_disabled {
|
||||
style.disabled()
|
||||
} else if is_mouse_over {
|
||||
if is_pressed {
|
||||
style.pressed()
|
||||
} else {
|
||||
style.hovered()
|
||||
}
|
||||
} else {
|
||||
style.active()
|
||||
};
|
||||
|
||||
let (content, _) = content.draw(
|
||||
self,
|
||||
&Defaults { text_color },
|
||||
content_layout,
|
||||
cursor_position,
|
||||
);
|
||||
|
||||
let primitive = if let Some(handle) = maybe_image {
|
||||
let background = Primitive::Image {
|
||||
handle: (handle, Rotation::None),
|
||||
bounds,
|
||||
color: Rgba::broadcast(255),
|
||||
};
|
||||
|
||||
Primitive::Group {
|
||||
primitives: vec![background, content],
|
||||
}
|
||||
} else {
|
||||
content
|
||||
};
|
||||
|
||||
let mouse_interaction = if is_mouse_over {
|
||||
mouse::Interaction::Pointer
|
||||
} else {
|
||||
mouse::Interaction::default()
|
||||
};
|
||||
|
||||
(primitive, mouse_interaction)
|
||||
}
|
||||
}
|
@ -6,14 +6,7 @@ use iced::mouse;
|
||||
use vek::Rgba;
|
||||
|
||||
impl image::Renderer for IcedRenderer {
|
||||
fn dimensions(&self, handle: image::Handle) -> (u32, u32) {
|
||||
self
|
||||
.cache
|
||||
.graphic_cache()
|
||||
.get_graphic_dims((handle, Rotation::None))
|
||||
// TODO: don't unwrap
|
||||
.unwrap()
|
||||
}
|
||||
fn dimensions(&self, handle: image::Handle) -> (u32, u32) { self.image_dims(handle) }
|
||||
|
||||
fn draw(
|
||||
&mut self,
|
||||
|
@ -1,4 +1,7 @@
|
||||
// TODO: reorganize modules (e.g. put all these in a widget submodule)
|
||||
mod aspect_ratio_container;
|
||||
mod background_container;
|
||||
mod button;
|
||||
mod column;
|
||||
mod compound_graphic;
|
||||
mod container;
|
||||
@ -7,6 +10,8 @@ mod row;
|
||||
mod space;
|
||||
mod text;
|
||||
|
||||
pub use button::Style as ButtonStyle;
|
||||
|
||||
use super::{
|
||||
super::graphic::{self, Graphic, TexId},
|
||||
cache::Cache,
|
||||
@ -157,6 +162,15 @@ impl IcedRenderer {
|
||||
self.cache.add_graphic(graphic)
|
||||
}
|
||||
|
||||
fn image_dims(&self, handle: super::widget::image::Handle) -> (u32, u32) {
|
||||
self
|
||||
.cache
|
||||
.graphic_cache()
|
||||
.get_graphic_dims((handle, Rotation::None))
|
||||
// TODO: don't unwrap
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn resize(&mut self, scaled_dims: Vec2<f32>, renderer: &mut Renderer) {
|
||||
self.win_dims = scaled_dims;
|
||||
|
||||
@ -582,9 +596,22 @@ fn default_scissor(renderer: &Renderer) -> Aabr<u16> {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: expose to user
|
||||
pub struct Defaults {
|
||||
pub text_color: iced::Color,
|
||||
}
|
||||
|
||||
impl Default for Defaults {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
text_color: iced::Color::WHITE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl iced::Renderer for IcedRenderer {
|
||||
// Default styling
|
||||
type Defaults = ();
|
||||
type Defaults = Defaults;
|
||||
// TODO: use graph of primitives to enable diffing???
|
||||
type Output = (Primitive, iced::mouse::Interaction);
|
||||
|
@ -28,7 +28,7 @@ impl text::Renderer for IcedRenderer {
|
||||
|
||||
fn draw(
|
||||
&mut self,
|
||||
_defaults: &Self::Defaults,
|
||||
defaults: &Self::Defaults,
|
||||
bounds: Rectangle,
|
||||
content: &str,
|
||||
size: u16,
|
||||
@ -38,25 +38,27 @@ impl text::Renderer for IcedRenderer {
|
||||
vertical_alignment: VerticalAlignment,
|
||||
) -> Self::Output {
|
||||
use glyph_brush::{HorizontalAlign, VerticalAlign};
|
||||
let h_align = match horizontal_alignment {
|
||||
HorizontalAlignment::Left => HorizontalAlign::Left,
|
||||
HorizontalAlignment::Center => HorizontalAlign::Center,
|
||||
HorizontalAlignment::Right => HorizontalAlign::Right,
|
||||
// glyph_brush thought it would be a great idea to change what the bounds and
|
||||
// position mean based on the alignment
|
||||
// TODO: add option to align based on the geometry of the rendered glyphs
|
||||
// instead of all possible glyphs
|
||||
let (x, h_align) = match horizontal_alignment {
|
||||
HorizontalAlignment::Left => (bounds.x, HorizontalAlign::Left),
|
||||
HorizontalAlignment::Center => (bounds.center_x(), HorizontalAlign::Center),
|
||||
HorizontalAlignment::Right => (bounds.x + bounds.width, HorizontalAlign::Right),
|
||||
};
|
||||
|
||||
let v_align = match vertical_alignment {
|
||||
VerticalAlignment::Top => VerticalAlign::Top,
|
||||
VerticalAlignment::Center => VerticalAlign::Center,
|
||||
VerticalAlignment::Bottom => VerticalAlign::Bottom,
|
||||
let (y, v_align) = match vertical_alignment {
|
||||
VerticalAlignment::Top => (bounds.y, VerticalAlign::Top),
|
||||
VerticalAlignment::Center => (bounds.center_y(), VerticalAlign::Center),
|
||||
VerticalAlignment::Bottom => (bounds.y + bounds.height, VerticalAlign::Bottom),
|
||||
};
|
||||
|
||||
let p_scale = self.p_scale;
|
||||
|
||||
let section = glyph_brush::Section {
|
||||
text: content,
|
||||
// TODO: do snap to pixel thing here IF it is being done down the line
|
||||
//screen_position: (bounds.x * p_scale, (self.win_dims.y - bounds.y) * p_scale),
|
||||
screen_position: (bounds.x * p_scale, bounds.y * p_scale),
|
||||
screen_position: (x * p_scale, y * p_scale),
|
||||
bounds: (bounds.width * p_scale, bounds.height * p_scale),
|
||||
scale: glyph_brush::rusttype::Scale::uniform(size as f32 * p_scale),
|
||||
layout: glyph_brush::Layout::Wrap {
|
||||
@ -86,7 +88,7 @@ impl text::Renderer for IcedRenderer {
|
||||
glyphs,
|
||||
//size: size as f32,
|
||||
bounds,
|
||||
linear_color: color.unwrap_or(Color::BLACK).into_linear().into(),
|
||||
linear_color: color.unwrap_or(defaults.text_color).into_linear().into(),
|
||||
/*font,
|
||||
*horizontal_alignment,
|
||||
*vertical_alignment, */
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub mod aspect_ratio_container;
|
||||
pub mod background_container;
|
||||
pub mod compound_graphic;
|
||||
pub mod image;
|
||||
|
189
voxygen/src/ui/ice/widget/aspect_ratio_container.rs
Normal file
189
voxygen/src/ui/ice/widget/aspect_ratio_container.rs
Normal file
@ -0,0 +1,189 @@
|
||||
use iced::{layout, Clipboard, Element, Event, Hasher, Layout, Length, Point, Rectangle, Widget};
|
||||
use std::{hash::Hash, u32};
|
||||
|
||||
// Note: it might be more efficient to make this generic over the content type?
|
||||
|
||||
enum AspectRatio<I> {
|
||||
/// Image Id
|
||||
Image(I),
|
||||
/// width / height
|
||||
Ratio(f32),
|
||||
}
|
||||
|
||||
impl<I: Hash> Hash for AspectRatio<I> {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
match self {
|
||||
Self::Image(i) => i.hash(state),
|
||||
Self::Ratio(r) => r.to_bits().hash(state),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides a container that takes on a fixed aspect ratio
|
||||
/// Thus, can be used to fix the aspect ratio of content if it is set to
|
||||
/// Length::Fill The aspect ratio may be based on that of an image, in which
|
||||
/// case the ratio is obtained from the renderer
|
||||
pub struct AspectRatioContainer<'a, M, R: self::Renderer> {
|
||||
max_width: u32,
|
||||
max_height: u32,
|
||||
aspect_ratio: AspectRatio<R::ImageHandle>,
|
||||
content: Element<'a, M, R>,
|
||||
}
|
||||
|
||||
impl<'a, M, R> AspectRatioContainer<'a, M, R>
|
||||
where
|
||||
R: self::Renderer,
|
||||
{
|
||||
pub fn new(content: impl Into<Element<'a, M, R>>) -> Self {
|
||||
Self {
|
||||
max_width: u32::MAX,
|
||||
max_height: u32::MAX,
|
||||
aspect_ratio: AspectRatio::Ratio(1.0),
|
||||
content: content.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the ratio (width/height)
|
||||
pub fn ratio(mut self, ratio: f32) -> Self {
|
||||
self.aspect_ratio = AspectRatio::Ratio(ratio);
|
||||
self
|
||||
}
|
||||
|
||||
/// Use the ratio of the provided image
|
||||
pub fn ratio_of_image(mut self, handle: R::ImageHandle) -> Self {
|
||||
self.aspect_ratio = AspectRatio::Image(handle);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn max_width(mut self, max_width: u32) -> Self {
|
||||
self.max_width = max_width;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn max_height(mut self, max_height: u32) -> Self {
|
||||
self.max_height = max_height;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, M, R> Widget<M, R> for AspectRatioContainer<'a, M, R>
|
||||
where
|
||||
R: self::Renderer,
|
||||
{
|
||||
fn width(&self) -> Length { Length::Fill }
|
||||
|
||||
fn height(&self) -> Length { Length::Fill }
|
||||
|
||||
fn layout(&self, renderer: &R, limits: &layout::Limits) -> layout::Node {
|
||||
let limits = limits
|
||||
.loose()
|
||||
.max_width(self.max_width)
|
||||
.max_height(self.max_height)
|
||||
.width(self.width())
|
||||
.height(self.height());
|
||||
|
||||
let aspect_ratio = match &self.aspect_ratio {
|
||||
AspectRatio::Image(handle) => {
|
||||
let (pixel_w, pixel_h) = renderer.dimensions(handle);
|
||||
|
||||
// Just in case
|
||||
// could convert to gracefully handling
|
||||
debug_assert!(pixel_w != 0);
|
||||
debug_assert!(pixel_h != 0);
|
||||
|
||||
pixel_w as f32 / pixel_h as f32
|
||||
},
|
||||
AspectRatio::Ratio(ratio) => *ratio,
|
||||
};
|
||||
|
||||
// We need to figure out the max width/height of the limits
|
||||
// and then adjust one down to meet the aspect ratio
|
||||
let max_size = limits.max();
|
||||
let (max_width, max_height) = (max_size.width as f32, max_size.height as f32);
|
||||
let max_aspect_ratio = max_width / max_height;
|
||||
let limits = if max_aspect_ratio > aspect_ratio {
|
||||
limits.max_width((max_height * aspect_ratio) as u32)
|
||||
} else {
|
||||
limits.max_height((max_width / aspect_ratio) as u32)
|
||||
};
|
||||
|
||||
let content = self.content.layout(renderer, &limits.loose());
|
||||
|
||||
layout::Node::with_children(limits.max(), vec![content])
|
||||
}
|
||||
|
||||
fn on_event(
|
||||
&mut self,
|
||||
event: Event,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
messages: &mut Vec<M>,
|
||||
renderer: &R,
|
||||
clipboard: Option<&dyn Clipboard>,
|
||||
) {
|
||||
self.content.on_event(
|
||||
event,
|
||||
layout.children().next().unwrap(),
|
||||
cursor_position,
|
||||
messages,
|
||||
renderer,
|
||||
clipboard,
|
||||
);
|
||||
}
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
defaults: &R::Defaults,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
) -> R::Output {
|
||||
renderer.draw(
|
||||
defaults,
|
||||
layout.bounds(),
|
||||
cursor_position,
|
||||
&self.content,
|
||||
layout.children().next().unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
fn hash_layout(&self, state: &mut Hasher) {
|
||||
struct Marker;
|
||||
std::any::TypeId::of::<Marker>().hash(state);
|
||||
|
||||
self.max_width.hash(state);
|
||||
self.max_height.hash(state);
|
||||
self.aspect_ratio.hash(state);
|
||||
// TODO: add pixel dims (need renderer)
|
||||
|
||||
self.content.hash_layout(state);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Renderer: iced::Renderer {
|
||||
/// The style supported by this renderer.
|
||||
//type Style: Default;
|
||||
/// The handle used by this renderer for images.
|
||||
type ImageHandle: Hash;
|
||||
|
||||
fn dimensions(&self, handle: &Self::ImageHandle) -> (u32, u32);
|
||||
|
||||
fn draw<M>(
|
||||
&mut self,
|
||||
defaults: &Self::Defaults,
|
||||
bounds: Rectangle,
|
||||
cursor_position: Point,
|
||||
//style: &Self::Style,
|
||||
content: &Element<'_, M, Self>,
|
||||
content_layout: Layout<'_>,
|
||||
) -> Self::Output;
|
||||
}
|
||||
|
||||
// They got to live ¯\_(ツ)_/¯
|
||||
impl<'a, M, R> From<AspectRatioContainer<'a, M, R>> for Element<'a, M, R>
|
||||
where
|
||||
R: 'a + self::Renderer,
|
||||
M: 'a,
|
||||
{
|
||||
fn from(widget: AspectRatioContainer<'a, M, R>) -> Element<'a, M, R> { Element::new(widget) }
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use iced::{layout, Element, Hasher, Layout, Length, Point, Size, Widget};
|
||||
use iced::{layout, Clipboard, Element, Event, Hasher, Layout, Length, Point, Size, Widget};
|
||||
use std::{hash::Hash, u32};
|
||||
|
||||
// Note: it might be more efficient to make this generic over the content type
|
||||
@ -63,7 +63,7 @@ pub trait Background<R: iced::Renderer>: Sized {
|
||||
fn width(&self) -> Length;
|
||||
fn height(&self) -> Length;
|
||||
fn aspect_ratio_fixed(&self) -> bool;
|
||||
fn pixel_dims(&self, renderer: &R) -> [u16; 2];
|
||||
fn pixel_dims(&self, renderer: &R) -> (u16, u16);
|
||||
fn draw(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
@ -158,7 +158,7 @@ where
|
||||
.width(self.width())
|
||||
.height(self.height());
|
||||
|
||||
let [pixel_w, pixel_h] = self.background.pixel_dims(renderer);
|
||||
let (pixel_w, pixel_h) = self.background.pixel_dims(renderer);
|
||||
let (horizontal_pad_frac, vertical_pad_frac, top_pad_frac, left_pad_frac) = {
|
||||
let Padding {
|
||||
top,
|
||||
@ -208,6 +208,10 @@ where
|
||||
// again, why is loose() used here?
|
||||
let mut content = self.content.layout(renderer, &limits.loose());
|
||||
|
||||
// TODO: handle cases where self and/or children are not Length::Fill
|
||||
// If fill use max_size
|
||||
//if match self.width(), self.height()
|
||||
|
||||
// This time we need to adjust up to meet the aspect ratio
|
||||
// so that the container is larger than the contents
|
||||
let mut content_size = content.size();
|
||||
@ -261,6 +265,25 @@ where
|
||||
layout::Node::with_children(size, vec![content])
|
||||
}
|
||||
|
||||
fn on_event(
|
||||
&mut self,
|
||||
event: Event,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
messages: &mut Vec<M>,
|
||||
renderer: &R,
|
||||
clipboard: Option<&dyn Clipboard>,
|
||||
) {
|
||||
self.content.on_event(
|
||||
event,
|
||||
layout.children().next().unwrap(),
|
||||
cursor_position,
|
||||
messages,
|
||||
renderer,
|
||||
clipboard,
|
||||
);
|
||||
}
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
|
@ -230,7 +230,9 @@ where
|
||||
|
||||
fn aspect_ratio_fixed(&self) -> bool { self.fix_aspect_ratio }
|
||||
|
||||
fn pixel_dims(&self, _renderer: &R) -> [u16; 2] { self.graphics_size }
|
||||
fn pixel_dims(&self, _renderer: &R) -> (u16, u16) {
|
||||
(self.graphics_size[0], self.graphics_size[1])
|
||||
}
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
|
@ -123,9 +123,9 @@ where
|
||||
|
||||
fn aspect_ratio_fixed(&self) -> bool { self.fix_aspect_ratio }
|
||||
|
||||
fn pixel_dims(&self, renderer: &R) -> [u16; 2] {
|
||||
fn pixel_dims(&self, renderer: &R) -> (u16, u16) {
|
||||
let (w, h) = renderer.dimensions(self.handle);
|
||||
[w as u16, h as u16]
|
||||
(w as u16, h as u16)
|
||||
}
|
||||
|
||||
fn draw(
|
||||
|
Loading…
Reference in New Issue
Block a user