Commit 4c400c68 authored by Florian Blasius's avatar Florian Blasius 🤘

[api update] stack update. Button pressed state.

parent c7e20d0b
// use std::{
// cell::{Cell, RefCell},
// collections::BTreeMap,
// rc::Rc,
// };
// use dces::prelude::{Entity, EntityComponentManager};
// use crate::{
// application::Tree,
// properties::{
// Bounds, Constraint, HorizontalAlignment, Margin, Orientation, VerticalAlignment, Visibility,
// },
// structs::{DirtySize, Position, Size, Spacer},
// theme::Theme,
// };
// use super::Layout;
// /// Stacks visual the children widgets vertical or horizontal.
// #[derive(Default)]
// pub struct StackLayout {
// desired_size: RefCell<DirtySize>,
// old_alignment: Cell<(VerticalAlignment, HorizontalAlignment)>,
// }
// impl StackLayout {
// pub fn new() -> Self {
// StackLayout::default()
// }
// }
// impl Layout for StackLayout {
// fn measure(
// &self,
// entity: Entity,
// ecm: &mut EntityComponentManager,
// tree: &Tree,
// layouts: &Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
// theme: &Theme,
// ) -> DirtySize {
// if Visibility::get(entity, ecm) == Visibility::Collapsed {
// self.desired_size.borrow_mut().set_size(0.0, 0.0);
// return self.desired_size.borrow().clone();
// }
// let horizontal_alignment = HorizontalAlignment::get(entity, ecm);
// let vertical_alignment = VerticalAlignment::get(entity, ecm);
// if horizontal_alignment != self.old_alignment.get().1
// || vertical_alignment != self.old_alignment.get().0
// {
// self.desired_size.borrow_mut().set_dirty(true);
// }
// let orientation = get_orientation(entity, ecm);
// let mut desired_size: (f64, f64) = (0.0, 0.0);
// for child in &tree.children[&entity] {
// if let Some(child_layout) = layouts.borrow().get(child) {
// let child_desired_size = child_layout.measure(*child, ecm, tree, layouts, theme);
// let child_margin = {
// if child_desired_size.width() > 0.0 && child_desired_size.height() > 0.0 {
// Margin::get(*child, ecm)
// } else {
// Margin::new()
// }
// };
// match orientation {
// Orientation::Horizontal => {
// desired_size.0 +=
// child_desired_size.width() + child_margin.left() + child_margin.right();
// desired_size.1 = desired_size.1.max(
// child_desired_size.height()
// + child_margin.top()
// + child_margin.bottom(),
// );
// }
// _ => {
// desired_size.0 = desired_size.0.max(
// child_desired_size.width() + child_margin.left() + child_margin.right(),
// );
// desired_size.1 += child_desired_size.height()
// + child_margin.top()
// + child_margin.bottom();
// }
// }
// let dirty = child_desired_size.dirty() || self.desired_size.borrow().dirty();
// self.desired_size.borrow_mut().set_dirty(dirty);
// }
// }
// self.desired_size
// .borrow_mut()
// .set_size(desired_size.0, desired_size.1);
// self.desired_size.borrow().clone()
// }
// fn arrange(
// &self,
// parent_size: (f64, f64),
// entity: Entity,
// ecm: &mut EntityComponentManager,
// tree: &Tree,
// layouts: &Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
// theme: &Theme,
// ) -> (f64, f64) {
// if !self.desired_size.borrow().dirty() {
// return self.desired_size.borrow().size();
// }
// let horizontal_alignment = HorizontalAlignment::get(entity, ecm);
// let vertical_alignment = VerticalAlignment::get(entity, ecm);
// let margin = Margin::get(entity, ecm);
// let constraint = Constraint::get(entity, ecm);
// let orientation = get_orientation(entity, ecm);
// let mut size_counter = 0.0;
// let size = constraint.perform((
// horizontal_alignment.align_width(
// parent_size.0,
// self.desired_size.borrow().width(),
// margin,
// ),
// vertical_alignment.align_height(
// parent_size.1,
// self.desired_size.borrow().height(),
// margin,
// ),
// ));
// if let Ok(bounds) = ecm.borrow_mut_component::<Bounds>(entity) {
// bounds.set_width(size.0);
// bounds.set_height(size.1);
// }
// let available_size = size;
// for child in &tree.children[&entity] {
// let mut child_desired_size = (0.0, 0.0);
// if let Some(child_layout) = layouts.borrow().get(child) {
// child_desired_size = child_layout.arrange(size, *child, ecm, tree, layouts, theme);
// }
// let child_margin = {
// if child_desired_size.0 > 0.0 && child_desired_size.1 > 0.0 {
// Margin::get(*child, ecm)
// } else {
// Margin::new()
// }
// };
// let child_horizontal_alignment = HorizontalAlignment::get(*child, ecm);
// let child_vertical_alignment = VerticalAlignment::get(*child, ecm);
// if let Ok(child_bounds) = ecm.borrow_mut_component::<Bounds>(*child) {
// match orientation {
// Orientation::Horizontal => {
// child_bounds.set_x(
// size_counter
// + child_horizontal_alignment.align_x(
// available_size.0,
// child_bounds.width(),
// child_margin,
// ),
// );
// child_bounds.set_y(child_vertical_alignment.align_y(
// available_size.1,
// child_bounds.height(),
// child_margin,
// ));
// size_counter +=
// child_bounds.width() + child_margin.left() + child_margin.right();
// }
// _ => {
// child_bounds.set_x(child_horizontal_alignment.align_x(
// available_size.0,
// child_bounds.width(),
// child_margin,
// ));
// child_bounds.set_y(
// size_counter
// + child_vertical_alignment.align_y(
// available_size.1,
// child_bounds.height(),
// child_margin,
// ),
// );
// size_counter +=
// child_bounds.height() + child_margin.top() + child_margin.bottom();
// }
// }
// }
// }
// self.desired_size.borrow_mut().set_dirty(false);
// size
// }
// }
// impl Into<Box<dyn Layout>> for StackLayout {
// fn into(self) -> Box<dyn Layout> {
// Box::new(self)
// }
// }
// // --- helpers ---
// fn get_orientation(entity: Entity, ecm: &EntityComponentManager) -> Orientation {
// if let Ok(orientation) = ecm.borrow_component::<Orientation>(entity) {
// return *orientation;
// }
// Orientation::default()
// }
// // --- helpers ---
use std::{
cell::{Cell, RefCell},
collections::BTreeMap,
rc::Rc,
};
use dces::prelude::{Entity, EntityComponentManager};
use crate::{
application::Tree,
properties::*,
structs::{DirtySize, Position, Size, Spacer},
enums::Alignment,
theme::Theme,
};
use super::Layout;
/// Stacks visual the children widgets vertical or horizontal.
#[derive(Default)]
pub struct StackLayout {
desired_size: RefCell<DirtySize>,
old_alignment: Cell<(Alignment, Alignment)>,
}
impl StackLayout {
pub fn new() -> Self {
StackLayout::default()
}
}
impl Layout for StackLayout {
fn measure(
&self,
entity: Entity,
ecm: &mut EntityComponentManager,
tree: &Tree,
layouts: &Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
theme: &Theme,
) -> DirtySize {
if Visibility::get(entity, ecm) == VisibilityValue::Collapsed {
self.desired_size.borrow_mut().set_size(0.0, 0.0);
return self.desired_size.borrow().clone();
}
let horizontal_alignment = HorizontalAlignment::get(entity, ecm);
let vertical_alignment = VerticalAlignment::get(entity, ecm);
if horizontal_alignment != self.old_alignment.get().1
|| vertical_alignment != self.old_alignment.get().0
{
self.desired_size.borrow_mut().set_dirty(true);
}
let orientation = Orientation::get(entity, ecm);
let mut desired_size: (f64, f64) = (0.0, 0.0);
for child in &tree.children[&entity] {
if let Some(child_layout) = layouts.borrow().get(child) {
let child_desired_size = child_layout.measure(*child, ecm, tree, layouts, theme);
let child_margin = {
if child_desired_size.width() > 0.0 && child_desired_size.height() > 0.0 {
Margin::get(*child, ecm)
} else {
Margin::default().0
}
};
match orientation {
OrientationValue::Horizontal => {
desired_size.0 +=
child_desired_size.width() + child_margin.left() + child_margin.right();
desired_size.1 = desired_size.1.max(
child_desired_size.height()
+ child_margin.top()
+ child_margin.bottom(),
);
}
_ => {
desired_size.0 = desired_size.0.max(
child_desired_size.width() + child_margin.left() + child_margin.right(),
);
desired_size.1 += child_desired_size.height()
+ child_margin.top()
+ child_margin.bottom();
}
}
let dirty = child_desired_size.dirty() || self.desired_size.borrow().dirty();
self.desired_size.borrow_mut().set_dirty(dirty);
}
}
self.desired_size
.borrow_mut()
.set_size(desired_size.0, desired_size.1);
self.desired_size.borrow().clone()
}
fn arrange(
&self,
parent_size: (f64, f64),
entity: Entity,
ecm: &mut EntityComponentManager,
tree: &Tree,
layouts: &Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
theme: &Theme,
) -> (f64, f64) {
if !self.desired_size.borrow().dirty() {
return self.desired_size.borrow().size();
}
let horizontal_alignment = HorizontalAlignment::get(entity, ecm);
let vertical_alignment = VerticalAlignment::get(entity, ecm);
let margin = Margin::get(entity, ecm);
let constraint = Constraint::get(entity, ecm);
let orientation = Orientation::get(entity, ecm);
let mut size_counter = 0.0;
let size = constraint.perform((
horizontal_alignment.align_measure(
parent_size.0,
self.desired_size.borrow().width(),
margin.left(),
margin.right()
),
vertical_alignment.align_measure(
parent_size.1,
self.desired_size.borrow().height(),
margin.top(),
margin.bottom()
),
));
if let Ok(bounds) = ecm.borrow_mut_component::<Bounds>(entity) {
bounds.set_width(size.0);
bounds.set_height(size.1);
}
let available_size = size;
for child in &tree.children[&entity] {
let mut child_desired_size = (0.0, 0.0);
if let Some(child_layout) = layouts.borrow().get(child) {
child_desired_size = child_layout.arrange(size, *child, ecm, tree, layouts, theme);
}
let child_margin = {
if child_desired_size.0 > 0.0 && child_desired_size.1 > 0.0 {
Margin::get(*child, ecm)
} else {
Margin::default().0
}
};
let child_horizontal_alignment = HorizontalAlignment::get(*child, ecm);
let child_vertical_alignment = VerticalAlignment::get(*child, ecm);
if let Ok(child_bounds) = ecm.borrow_mut_component::<Bounds>(*child) {
match orientation {
OrientationValue::Horizontal => {
child_bounds.set_x(
size_counter
+ child_horizontal_alignment.align_position(
available_size.0,
child_bounds.width(),
child_margin.left(),
child_margin.right()
),
);
child_bounds.set_y(child_vertical_alignment.align_position(
available_size.1,
child_bounds.height(),
child_margin.top(),
child_margin.bottom()
));
size_counter +=
child_bounds.width() + child_margin.left() + child_margin.right();
}
_ => {
child_bounds.set_x(child_horizontal_alignment.align_position(
available_size.0,
child_bounds.width(),
child_margin.left(),
child_margin.right()
));
child_bounds.set_y(
size_counter
+ child_vertical_alignment.align_position(
available_size.1,
child_bounds.height(),
child_margin.top(),
child_margin.bottom()
),
);
size_counter +=
child_bounds.height() + child_margin.top() + child_margin.bottom();
}
}
}
}
self.desired_size.borrow_mut().set_dirty(false);
size
}
}
impl Into<Box<dyn Layout>> for StackLayout {
fn into(self) -> Box<dyn Layout> {
Box::new(self)
}
}
\ No newline at end of file
......@@ -70,6 +70,7 @@ macro_rules! widget {
name: Option<Name>,
horizontal_alignment: HorizontalAlignment,
vertical_alignment: VerticalAlignment,
enabled: Enabled,
visibility: Visibility,
$(
$(
......@@ -113,6 +114,11 @@ macro_rules! widget {
self.attach(visibility)
}
/// Sets or shares the enabled property.
pub fn enabled<P: Into<PropertySource<Enabled>>>(self, enabled: P) -> Self {
self.attach(enabled)
}
// todo: constraint also by with min max, ...
/// Sets the debug name of the widget.
......@@ -154,6 +160,7 @@ macro_rules! widget {
horizontal_alignment: HorizontalAlignment::default(),
vertical_alignment: VerticalAlignment::default(),
visibility: Visibility::default(),
enabled: Enabled(false),
$(
$(
$property: None,
......
......@@ -9,7 +9,7 @@ property!(
// --- Trait implementations ---
/// Used to align the position of a widget vertical.
pub trait AlignHorizontal {
pub trait HorizontalAlignmentExtension {
/// Calculates the x position of the widget depending on the available width, the goal width
/// margin and Horizontal alignment.
fn align_x(&self, available_height: f64, height: f64, margin: Margin) -> f64;
......@@ -19,13 +19,12 @@ pub trait AlignHorizontal {
fn align_width(&self, available_height: f64, height: f64, margin: Margin) -> f64;
}
impl AlignHorizontal for HorizontalAlignment {
impl HorizontalAlignmentExtension for HorizontalAlignment {
fn align_x(&self, available_height: f64, height: f64, margin: Margin) -> f64 {
self.0
.align_position(available_height, height, margin.left(), margin.right())
}
fn align_width(&self, available_height: f64, height: f64, margin: Margin) -> f64 {
self.0
.align_measure(available_height, height, margin.left(), margin.right())
......
// /// Used to define the orientation of the `Stack`.
// #[derive(Copy, Clone, Debug, PartialEq)]
// pub enum Orientation {
// /// Vertical orientation.
// Vertical,
/// Is used to control the orientation of the `Stack`.
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum OrientationValue {
/// Vertical orientation.
Vertical,
// /// Horizontal orientation.
// Horizontal,
// }
/// Horizontal orientation.
Horizontal,
}
// property!(
// Orientation,
// OrientationProperty,
// orientation,
// shared_orientation
// );
impl Default for OrientationValue {
fn default() -> OrientationValue {
OrientationValue::Vertical
}
}
// impl Default for Orientation {
// fn default() -> Self {
// Orientation::Vertical
// }
// }
property!(
/// `Orientation` describes the orientation of the `Stack`.
Orientation(OrientationValue)
);
// impl From<&str> for Orientation {
// fn from(t: &str) -> Self {
// match t {
// "Horizontal" | "horizontal" => Orientation::Horizontal,
// _ => Orientation::Vertical,
// }
// }
// }
// --- Conversions ---
impl From<&str> for Orientation {
fn from(t: &str) -> Self {
match t {
"Horizontal" | "horizontal" => Orientation::from(OrientationValue::Horizontal),
_ => Orientation::from(OrientationValue::Vertical),
}
}
}
impl Into<PropertySource<Orientation>> for &str {
fn into(self) -> PropertySource<Orientation> {
PropertySource::Value(Orientation::from(self))
}
}
......@@ -9,7 +9,7 @@ property!(
// --- Trait implementations ---
/// Used to align the position of a widget vertical.
pub trait AlignVertical {
pub trait VerticalAlignmentExtension {
/// Calculates the y position of the widget depending on the available height, the goal height
/// margin and Vertical alignment.
fn align_y(&self, available_height: f64, height: f64, margin: Margin) -> f64;
......@@ -19,12 +19,11 @@ pub trait AlignVertical {
fn align_height(&self, available_height: f64, height: f64, margin: Margin) -> f64;
}
impl AlignVertical for VerticalAlignment {
impl VerticalAlignmentExtension for VerticalAlignment {
fn align_y(&self, available_height: f64, height: f64, margin: Margin) -> f64 {
self.0
.align_position(available_height, height, margin.top(), margin.bottom())
}
fn align_height(&self, available_height: f64, height: f64, margin: Margin) -> f64 {
self.0
......
// /// The struct `MouseOver` represents the current mouse over state of a widget.
// #[derive(Default, Copy, Clone)]
// pub struct MouseOver(pub bool);
// property!(MouseOver, MouseOverProperty, mouse_over, shared_mouse_over);
// impl From<bool> for MouseOver {
// fn from(t: bool) -> Self {
// MouseOver(t)
// }
// }
property!(
/// `MouseOver` describes the mouse over state of a widget.
MouseOver(bool)
......
......@@ -41,7 +41,10 @@ widget!(
font: Font,
/// Sets or shares the css selector property.
selector: Selector
selector: Selector,
/// Sets or shares the pressed property.
pressed: Pressed
}
);
......@@ -57,6 +60,7 @@ impl Template for Button {
.text("")
.font_size(fonts::FONT_SIZE_12)
.font(fonts::font_into_box(fonts::ROBOTO_REGULAR_FONT))
.pressed(false)
.child(
Container::create()
.background(id)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment