Layout fixes (#6066)

This commit is contained in:
Adam Obuchowicz 2023-03-25 02:28:35 +01:00 committed by GitHub
parent 58f2c7643f
commit 866a58a0cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 661 additions and 435 deletions

File diff suppressed because it is too large Load Diff

View File

@ -111,7 +111,7 @@ impl From<i32> for Unit {
#[derive(Clone, Copy, Debug, Default, PartialEq, From)]
pub enum Size {
/// In this mode, the display object size will be set to the size of its content. In case of
/// siplay object with no children, their size will be set to 0.
/// display object with no children, their size will be set to 0.
#[default]
Hug,
/// In this mode, the display object size is provided explicitly.
@ -129,6 +129,11 @@ impl Size {
matches!(self, Size::Fixed(_))
}
/// Checks whether the resizing mode is directly dependant on computed parent size.
pub fn depends_on_parent_size(self) -> bool {
matches!(self, Size::Fixed(Unit::Percent(_)))
}
/// Matcher for the [`Pixels`] variant.
pub fn as_pixels(self) -> Option<f32> {
match self {

View File

@ -6,12 +6,12 @@
#![allow(clippy::bool_to_int_with_if)]
#![allow(clippy::let_and_return)]
use ensogl_core::animation;
use ensogl_core::data::color::Rgba;
use ensogl_core::display::shape::*;
use ensogl_core::display::world::*;
use ensogl_core::prelude::*;
use ensogl_core::data::color;
use ensogl_core::display;
use ensogl_core::display::navigation::navigator::Navigator;
use ensogl_core::display::object::ObjectOps;
@ -25,10 +25,11 @@ mod rectangle {
use super::*;
ensogl_core::shape! {
(style: Style, color: Vector4<f32>) {
let color = Var::<color::Rgba>::from(color);
let width = Var::<Pixels>::from("input_size.x");
let height = Var::<Pixels>::from("input_size.y");
let rect = Rect((&width, &height)).corners_radius(10.0.px());
let shape = rect.fill(color::Rgba(0.0,0.0,0.0,0.2));
let rect = Rect((&width, &height)).corners_radius(5.0.px());
let shape = rect.fill(color);
shape.into()
}
}
@ -45,45 +46,68 @@ mod rectangle {
#[entry_point]
#[allow(dead_code)]
pub fn main() {
let world = World::new().displayed_in("root");
let world = World::new().displayed_in("root").leak();
let scene = &world.default_scene;
let camera = scene.camera().clone_ref();
let navigator = Navigator::new(scene, &camera);
let _navigator = Navigator::new(scene, &camera).leak();
let rect1 = rectangle::View::new();
rect1.set_size(Vector2::new(100.0, 100.0));
rect1.color.set(color::Rgba::new(0.5, 0.0, 0.0, 0.3).into());
let root = scene.new_child_named("root").leak();
root.use_auto_layout().set_gap((5.0, 5.0));
let rect2 = rectangle::View::new();
rect2.set_size(Vector2::new(100.0, 100.0));
rect2.color.set(color::Rgba::new(0.5, 0.0, 0.0, 0.3).into());
let rect1 = root.new_child_named("rect1").leak();
let rect1_bg = rect1.new_child_named("rect1_bg").leak();
rect1_bg.use_auto_layout().allow_grow().set_size((0.0, 0.0));
let root = display::object::Instance::new();
root.set_size(Vector2::new(300.0, 100.0));
root.use_auto_layout();
root.add_child(&rect1);
let rect1_bg_shape = rectangle::View::new().leak();
rect1_bg.add_child(&rect1_bg_shape);
rect1_bg_shape.color.set(Rgba::new(0.0, 0.0, 0.0, 0.3).into());
rect1_bg_shape.allow_grow().set_size((0.0, 0.0));
let rect1_content = rect1.new_child_named("rect1_content").leak();
rect1_content.use_auto_layout().set_gap((5.0, 5.0)).set_padding_all(5.0);
let inner1 = rectangle::View::new().leak();
rect1_content.add_child(&inner1);
inner1.set_size((40, 40)).set_alignment_bottom();
inner1.color.set(Rgba::new(1.0, 0.0, 0.0, 0.4).into());
let inner2 = rectangle::View::new().leak();
rect1_content.add_child(&inner2);
inner2.set_size((40, 40)).set_alignment_center();
inner2.color.set(Rgba::new(0.0, 1.0, 0.0, 0.4).into());
let inner3 = rectangle::View::new().leak();
rect1_content.add_child(&inner3);
inner3.set_size((40, 40)).set_alignment_top();
inner3.color.set(Rgba::new(0.0, 0.0, 1.0, 0.4).into());
let rect2 = rectangle::View::new().leak();
root.add_child(&rect2);
world.add_child(&root);
rect2.set_size(Vector2::new(100.0, 100.0));
rect2.color.set(Rgba::new(0.5, 0.0, 0.0, 0.3).into());
warn!("rect1: {:?}", rect1.display_object());
let rect2_inner = rectangle::View::new().leak();
rect2.add_child(&rect2_inner);
rect2_inner.set_size((40, 40));
rect2_inner.color.set(Rgba::new(1.0, 1.0, 1.0, 0.4).into());
let r = rect1.clone_ref();
let mut i = 0;
let mut logged = false;
world
.on
.before_frame
.add(move |_| {
if i == 10 {
warn!("rect1: {:?}", r.display_object());
// warn!("rect1 sprite: {:?}", r.sprite.borrow().display_object());
.add(move |t: animation::TimeInfo| {
let s = t.since_animation_loop_started.as_s();
let x = (s * std::f32::consts::PI).sin() * 30.0 + 50.0;
let y = (s * 1.3 * std::f32::consts::PI).cos() * 40.0 + 50.0;
inner2.set_size((x, y));
if !logged {
logged = true;
warn!("rect1: {:?}", rect1.display_object());
warn!("rect2: {:?}", rect2.display_object());
}
i += 1;
})
.forget();
world.keep_alive_forever();
mem::forget(navigator);
mem::forget(root);
mem::forget(rect1);
mem::forget(rect2);
}

View File

@ -325,7 +325,6 @@ pub fn main() {
/// Initialize a `SliderCollection` and do not drop it.
fn init(app: &Application) {
let slider_collection = app.new_view::<SliderCollection>();
let slider_collection = app.new_view::<SliderCollection>().leak();
app.display.add_child(&slider_collection);
Leak::new(slider_collection);
}

View File

@ -1,7 +1,9 @@
//! `Leak` is a utility struct that prevents the wrapped value from being dropped when `Leak` is
//! being dropped. This is achieved by passing the contained value to `std::mem::forget` in the
//! drop implementation of `Leak`. Can bue used for examples to keep components alive for the whole
//! lifetime of the application.
//! `Leak` is a utility trait that prevents the wrapped value from being dropped when `Leak` is
//! being dropped. This is achieved by wrapping it with [`ManuallyDrop`], which will prevent the
//! [`Drop`] handler from being called when local variable out of scope. Can be used for example
//! to keep components alive for the whole lifetime of the application.
use std::mem::ManuallyDrop;
@ -9,35 +11,13 @@
// === Leak ===
// ============
/// Wrapper that will prevent the wrapped value from being dropped. Instead, the value will be
/// leaked when the `Leak` is dropped.
#[derive(Debug)]
pub struct Leak<T> {
value: Option<T>,
}
impl<T> Leak<T> {
/// Constructor. The passed value will be prevented from being dropped. This will cause memory
/// leaks.
pub fn new(value: T) -> Self {
Self { value: Some(value) }
}
/// Return a reference to the wrapped value.
pub fn inner(&self) -> &T {
// Guaranteed to never panic as this is always initialised with `Some` in the constructor.
self.value.as_ref().unwrap()
}
/// Return a mutable reference to the wrapped value.
pub fn inner_mut(&mut self) -> &mut T {
// Guaranteed to never panic as this is always initialised with `Some` in the constructor.
self.value.as_mut().unwrap()
/// Wrapper that will prevent the wrapped value from being dropped. Equivalent to calling
/// `mem::forget` on the wrapped value at the end of its scope.
pub trait Leak {
fn leak(self) -> ManuallyDrop<Self>
where Self: Sized {
ManuallyDrop::new(self)
}
}
impl<T> Drop for Leak<T> {
fn drop(&mut self) {
std::mem::forget(self.value.take());
}
}
impl<T> Leak for T {}