Commit 3d96b22e authored by Florian Blasius's avatar Florian Blasius 🤘
Browse files

[refactroing] styling properties, theme updates.

parent dd85e134
......@@ -17,9 +17,7 @@ use crate::{
theme::{Selector, Theme},
};
use super::{
get_constraint, get_horizontal_alignment, get_vertical_alignment, get_visibility, Layout,
};
use super::Layout;
/// Fixed size layout is defined by fixed bounds like the size of an image or the size of a text.
#[derive(Default)]
......@@ -43,13 +41,13 @@ impl Layout for FixedSizeLayout {
layouts: &Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
theme: &Theme,
) -> DirtySize {
if get_visibility(entity, ecm) == Visibility::Collapsed {
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 = get_horizontal_alignment(entity, ecm);
let vertical_alignment = get_vertical_alignment(entity, ecm);
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
......@@ -124,7 +122,7 @@ impl Layout for FixedSizeLayout {
// -- todo will be removed after orbgl merge --
let constraint = get_constraint(entity, ecm);
let constraint = Constraint::get(entity, ecm);
if constraint.width() > 0.0 {
self.desired_size.borrow_mut().set_width(constraint.width());
......
......@@ -9,17 +9,14 @@ use dces::prelude::{Entity, EntityComponentManager};
use crate::{
application::Tree,
properties::{
Bounds, ColumnSpan, ColumnWidth, Columns, GridColumn, GridRow, HorizontalAlignment, Margin,
RowHeight, RowSpan, Rows, VerticalAlignment, Visibility,
Bounds, ColumnSpan, ColumnWidth, Columns, Constraint, GridColumn, GridRow,
HorizontalAlignment, Margin, RowHeight, RowSpan, Rows, VerticalAlignment, Visibility,
},
structs::{DirtySize, Position, Size, Spacer},
theme::Theme,
};
use super::{
get_constraint, get_horizontal_alignment, get_margin, get_vertical_alignment, get_visibility,
Layout,
};
use super::Layout;
/// Orders its children in a grid layout with columns and rows. If now columns and rows are defined
/// the gird layout could also be used as alignment layout.
......@@ -106,13 +103,13 @@ impl Layout for GridLayout {
layouts: &Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
theme: &Theme,
) -> DirtySize {
if get_visibility(entity, ecm) == Visibility::Collapsed {
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 = get_horizontal_alignment(entity, ecm);
let vertical_alignment = get_vertical_alignment(entity, ecm);
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
......@@ -144,7 +141,7 @@ impl Layout for GridLayout {
.borrow_mut()
.set_size(desired_size.0, desired_size.1);
let size = get_constraint(entity, ecm).perform(self.desired_size.borrow().size());
let size = Constraint::get(entity, ecm).perform(self.desired_size.borrow().size());
self.desired_size.borrow_mut().set_size(size.0, size.1);
self.desired_size.borrow().clone()
......@@ -163,10 +160,10 @@ impl Layout for GridLayout {
return self.desired_size.borrow().size();
}
let horizontal_alignment = get_horizontal_alignment(entity, ecm);
let vertical_alignment = get_vertical_alignment(entity, ecm);
let margin = get_margin(entity, ecm);
let constraint = get_constraint(entity, ecm);
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 size = constraint.perform((
horizontal_alignment.align_width(
......@@ -188,7 +185,7 @@ impl Layout for GridLayout {
// calculates the auto column widths
for child in &tree.children[&entity] {
let margin = get_margin(*child, ecm);
let margin = Margin::get(*child, ecm);
if let Ok(grid_column) = ecm.borrow_component::<GridColumn>(*child) {
if let Ok(columns) = ecm.borrow_component::<Columns>(entity) {
......@@ -386,8 +383,8 @@ impl Layout for GridLayout {
}
};
let c_vertical_alignment = get_vertical_alignment(*child, ecm);
let c_horizontal_alignment = get_horizontal_alignment(*child, ecm);
let c_vertical_alignment = VerticalAlignment::get(*child, ecm);
let c_horizontal_alignment = HorizontalAlignment::get(*child, ecm);
let has_columns = if let Ok(columns) = ecm.borrow_component::<Columns>(entity) {
columns.len() > 0
......
use std::{cell::RefCell, collections::BTreeMap, rc::Rc};
use dces::prelude::{Component, Entity, EntityComponentManager};
use dces::prelude::{Entity, EntityComponentManager};
use crate::{
application::Tree,
properties::{Constraint, HorizontalAlignment, Margin, Padding, VerticalAlignment, Visibility},
structs::DirtySize,
theme::Theme,
widget::get_property,
};
pub use self::fixed_size::FixedSizeLayout;
......@@ -46,45 +47,3 @@ pub trait Layout {
theme: &Theme,
) -> (f64, f64);
}
// --- helpers ---
fn get_property<T>(entity: Entity, ecm: &EntityComponentManager) -> T
where
T: Clone + Component + Default,
{
ecm.borrow_component::<T>(entity)
.map(|r| r.clone())
.unwrap_or_default()
}
pub fn get_vertical_alignment(entity: Entity, ecm: &EntityComponentManager) -> VerticalAlignment {
get_property::<VerticalAlignment>(entity, ecm)
}
pub fn get_horizontal_alignment(
entity: Entity,
ecm: &EntityComponentManager,
) -> HorizontalAlignment {
get_property::<HorizontalAlignment>(entity, ecm)
}
pub fn get_margin(entity: Entity, ecm: &EntityComponentManager) -> Margin {
get_property::<Margin>(entity, ecm)
}
pub fn get_padding(entity: Entity, ecm: &EntityComponentManager) -> Padding {
get_property::<Padding>(entity, ecm)
}
pub fn get_constraint(entity: Entity, ecm: &EntityComponentManager) -> Constraint {
get_property::<Constraint>(entity, ecm)
}
pub fn get_visibility(entity: Entity, ecm: &EntityComponentManager) -> Visibility {
get_property::<Visibility>(entity, ecm)
}
// todo provide helpers for basic properties get_.. borrow_.. borrow_mut..
// --- helpers ---
use std::{cell::{Cell, RefCell}, collections::BTreeMap, rc::Rc};
use std::{
cell::{Cell, RefCell},
collections::BTreeMap,
rc::Rc,
};
use dces::prelude::{Entity, EntityComponentManager};
use crate::{
application::Tree,
properties::{Bounds, Visibility, VerticalAlignment, HorizontalAlignment},
properties::{
Bounds, Constraint, HorizontalAlignment, Margin, Padding, VerticalAlignment, Visibility,
},
structs::{DirtySize, Position, Size, Spacer},
theme::Theme,
};
use super::{
get_constraint, get_horizontal_alignment, get_margin, get_padding, get_vertical_alignment,
get_visibility, Layout,
};
use super::Layout;
/// Add padding to the widget.
#[derive(Default)]
......@@ -36,30 +39,32 @@ impl Layout for PaddingLayout {
layouts: &Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
theme: &Theme,
) -> DirtySize {
if get_visibility(entity, ecm) == Visibility::Collapsed {
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 = get_horizontal_alignment(entity, ecm);
let vertical_alignment = get_vertical_alignment(entity, ecm);
let horizontal_alignment = HorizontalAlignment::get(entity, ecm);
let vertical_alignment = VerticalAlignment::get(entity, ecm);
if horizontal_alignment != self.old_alignment.get().1
if horizontal_alignment != self.old_alignment.get().1
|| vertical_alignment != self.old_alignment.get().0
{
self.desired_size.borrow_mut().set_dirty(true);
}
let constraint = get_constraint(entity, ecm);
let constraint = Constraint::get(entity, ecm);
if constraint.width() > 0.0 {
self.desired_size.borrow_mut().set_width(constraint.width());
}
if constraint.height() > 0.0 {
self.desired_size.borrow_mut().set_height(constraint.height());
self.desired_size
.borrow_mut()
.set_height(constraint.height());
}
let padding = get_padding(entity, ecm);
let padding = Padding::get(entity, ecm);
for child in &tree.children[&entity] {
if let Some(child_layout) = layouts.borrow().get(child) {
......@@ -67,11 +72,9 @@ impl Layout for PaddingLayout {
let mut desired_size = self.desired_size.borrow().size();
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_dirty(dirty);
let child_margin = get_margin(*child, ecm);
let child_margin = Margin::get(*child, ecm);
desired_size.0 = desired_size.0.max(
child_desired_size.width()
......@@ -110,11 +113,11 @@ impl Layout for PaddingLayout {
return self.desired_size.borrow().size();
}
let horizontal_alignment = get_horizontal_alignment(entity, ecm);
let vertical_alignment = get_vertical_alignment(entity, ecm);
let margin = get_margin(entity, ecm);
let padding = get_padding(entity, ecm);
let constraint = get_constraint(entity, ecm);
let horizontal_alignment = HorizontalAlignment::get(entity, ecm);
let vertical_alignment = VerticalAlignment::get(entity, ecm);
let margin = Margin::get(entity, ecm);
let padding = Padding::get(entity, ecm);
let constraint = Constraint::get(entity, ecm);
let size = constraint.perform((
horizontal_alignment.align_width(
......@@ -129,7 +132,6 @@ impl Layout for PaddingLayout {
),
));
if let Ok(bounds) = ecm.borrow_mut_component::<Bounds>(entity) {
bounds.set_width(size.0);
bounds.set_height(size.1);
......@@ -141,14 +143,14 @@ impl Layout for PaddingLayout {
);
for child in &tree.children[&entity] {
let child_margin = get_margin(*child, ecm);
let child_margin = Margin::get(*child, ecm);
if let Some(child_layout) = layouts.borrow().get(child) {
child_layout.arrange(available_size, *child, ecm, tree, layouts, theme);
}
let child_horizontal_alignment = get_horizontal_alignment(*child, ecm);
let child_vertical_alignment = get_vertical_alignment(*child, ecm);
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) {
child_bounds.set_x(
......
......@@ -9,15 +9,15 @@ use dces::prelude::{Entity, EntityComponentManager};
use crate::{
application::Tree,
layout::Layout,
properties::{Bounds, HorizontalAlignment, Offset, VerticalAlignment, Visibility},
properties::{
Bounds, Constraint, HorizontalAlignment, Margin, Offset, Padding, VerticalAlignment,
Visibility,
},
structs::{DirtySize, Position, Size},
theme::Theme,
};
use super::{
get_constraint, get_horizontal_alignment, get_margin, get_vertical_alignment, get_visibility,
};
use super::Layout;
/// IMPORTANT: The scroll layout will only work for the text box now. A update will follow!!!!
#[derive(Default)]
......@@ -43,13 +43,13 @@ impl Layout for ScrollLayout {
layouts: &Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
theme: &Theme,
) -> DirtySize {
if get_visibility(entity, ecm) == Visibility::Collapsed {
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 = get_horizontal_alignment(entity, ecm);
let vertical_alignment = get_vertical_alignment(entity, ecm);
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
......@@ -57,7 +57,7 @@ impl Layout for ScrollLayout {
self.desired_size.borrow_mut().set_dirty(true);
}
let constraint = get_constraint(entity, ecm);
let constraint = Constraint::get(entity, ecm);
if constraint.width() > 0.0 {
self.desired_size.borrow_mut().set_width(constraint.width());
......@@ -103,10 +103,11 @@ impl Layout for ScrollLayout {
return self.desired_size.borrow().size();
}
let horizontal_alignment = get_horizontal_alignment(entity, ecm);
let vertical_alignment = get_vertical_alignment(entity, ecm);
let margin = get_margin(entity, ecm);
let constraint = get_constraint(entity, ecm);
let horizontal_alignment = HorizontalAlignment::get(entity, ecm);
let vertical_alignment = VerticalAlignment::get(entity, ecm);
let margin = Margin::get(entity, ecm);
let padding = Padding::get(entity, ecm);
let constraint = Constraint::get(entity, ecm);
let size = constraint.perform((
horizontal_alignment.align_width(
......@@ -148,8 +149,8 @@ impl Layout for ScrollLayout {
for child in &tree.children[&entity] {
// let child_margin = get_margin(*child, ecm);
let mut child_size = old_child_size;
let child_vertical_alignment = get_vertical_alignment(*child, ecm);
let child_margin = get_margin(*child, ecm);
let child_vertical_alignment = VerticalAlignment::get(*child, ecm);
let child_margin = Margin::get(*child, ecm);
if let Some(child_layout) = layouts.borrow().get(child) {
child_size =
......
......@@ -8,15 +8,14 @@ use dces::prelude::{Entity, EntityComponentManager};
use crate::{
application::Tree,
properties::{Bounds, HorizontalAlignment, Margin, Orientation, VerticalAlignment, Visibility},
properties::{
Bounds, Constraint, HorizontalAlignment, Margin, Orientation, VerticalAlignment, Visibility,
},
structs::{DirtySize, Position, Size, Spacer},
theme::Theme,
};
use super::{
get_constraint, get_horizontal_alignment, get_margin, get_vertical_alignment, get_visibility,
Layout,
};
use super::Layout;
/// Stacks visual the children widgets vertical or horizontal.
#[derive(Default)]
......@@ -40,13 +39,13 @@ impl Layout for StackLayout {
layouts: &Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
theme: &Theme,
) -> DirtySize {
if get_visibility(entity, ecm) == Visibility::Collapsed {
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 = get_horizontal_alignment(entity, ecm);
let vertical_alignment = get_vertical_alignment(entity, ecm);
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
......@@ -62,7 +61,7 @@ impl Layout for StackLayout {
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 {
get_margin(*child, ecm)
Margin::get(*child, ecm)
} else {
Margin::new()
}
......@@ -112,10 +111,10 @@ impl Layout for StackLayout {
return self.desired_size.borrow().size();
}
let horizontal_alignment = get_horizontal_alignment(entity, ecm);
let vertical_alignment = get_vertical_alignment(entity, ecm);
let margin = get_margin(entity, ecm);
let constraint = get_constraint(entity, ecm);
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;
......@@ -147,14 +146,14 @@ impl Layout for StackLayout {
let child_margin = {
if child_desired_size.0 > 0.0 && child_desired_size.1 > 0.0 {
get_margin(*child, ecm)
Margin::get(*child, ecm)
} else {
Margin::new()
}
};
let child_horizontal_alignment = get_horizontal_alignment(*child, ecm);
let child_vertical_alignment = get_vertical_alignment(*child, ecm);
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 {
......
......@@ -9,12 +9,12 @@ use dces::prelude::{Entity, EntityComponentManager};
use crate::{
application::Tree,
backend::{FontMeasure, FONT_MEASURE},
properties::{Bounds, Margin, Offset, Text, TextSelection, Visibility},
properties::{Bounds, Constraint, Margin, Offset, Text, TextSelection, Visibility, VerticalAlignment},
structs::{DirtySize, Size, Spacer},
theme::{Selector, Theme},
};
use super::{get_constraint, get_margin, get_vertical_alignment, get_visibility, Layout};
use super::Layout;
/// The text selection layout is used to measure and arrange a text selection cursor.
#[derive(Default)]
......@@ -44,12 +44,12 @@ impl Layout for TextSelectionLayout {
layouts: &Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
theme: &Theme,
) -> DirtySize {
if get_visibility(entity, ecm) == Visibility::Collapsed {
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 constraint = get_constraint(entity, ecm);
let constraint = Constraint::get(entity, ecm);
if let Ok(selection) = ecm.borrow_component::<TextSelection>(entity) {
if *selection != self.old_text_selection.get() {
......@@ -108,8 +108,8 @@ impl Layout for TextSelectionLayout {
let mut pos = 0.0;
let mut size = self.desired_size.borrow().size();
let vertical_alignment = get_vertical_alignment(entity, ecm);
let margin = get_margin(entity, ecm);
let vertical_alignment = VerticalAlignment::get(entity, ecm);
let margin = Margin::get(entity, ecm);
size.1 = vertical_alignment.align_height(parent_size.1, size.1, margin);
......
......@@ -66,7 +66,9 @@ macro_rules! template {
#[macro_export]
macro_rules! property {
($type:ident, $property:ident, $method:ident, $shared_method:ident) => {
use crate::widget::{SharedProperty, Template};
use dces::prelude::{Entity, EntityComponentManager};
use crate::widget::{SharedProperty, Template, get_property, get_property_by_widget, has_property, WidgetContainer};
pub trait $property: Sized + From<Template> + Into<Template> {
/// Transforms the property into a template.
......@@ -84,5 +86,19 @@ macro_rules! property {
self.template(|template| template.shared_property($method.into()))
}
}
impl $type {
pub fn get(entity: Entity, ecm: &EntityComponentManager) -> $type {
get_property::<$type>(entity, ecm)
}
pub fn get_by_widget(widget: &WidgetContainer) -> $type {
get_property_by_widget::<$type>(widget)
}
pub fn has(widget: &WidgetContainer) -> bool {
has_property::<$type>(widget)
}
}
};
}
\ No newline at end of file
use super::ScrollMode;
/// The `ScrollViewerMode` struct is used to define the vertical and horizontal scroll behavior of the `ScrollViewer`.
#[derive(Default)]
#[derive(Clone, Default, PartialEq)]
pub struct ScrollViewerMode {
/// Vertical scroll mode.
pub vertical: ScrollMode,
......
/// The struct `Enabled` is to enable / disable a widget. If `Enabled` is set to `false` the widget could have a different look
/// and its event handler will not be called. All children inherit the enabled state of its parent.
#[derive(Default)]
#[derive(Clone, Default, PartialEq)]
pub struct Enabled(pub bool);
property!(Enabled, EnabledProperty, enabled, shared_enabled);
......
use crate::structs::Brush;
use crate::structs::{Brush, Color};
/// Used to draw the background brush of a widget.
#[derive(Clone)]
pub struct Background(pub Brush);
property!(
......@@ -10,9 +11,15 @@ property!(
shared_background
);
impl From<Background> for Color {
fn from(b: Background) -> Color {
b.0.into()
}
}
impl Default for Background {
fn default() -> Background {
"#000000".into()
"#000000".into()
}
}
......@@ -20,4 +27,4 @@ impl From<&str> for Background {
fn from(s: &str) -> Background {
Background(s.into())
}
}
\ No newline at end of file
}
use crate::structs::Brush;
use crate::structs::{Brush, Color};
/// Used to draw the border brush of a widget.
#[derive(Clone)]
pub struct BorderBrush(pub Brush);
property!(
......@@ -10,6 +11,12 @@ property!(
shared_border_brush
);
impl From<BorderBrush> for Color {
fn from(b: BorderBrush) -> Color {
b.0.into()
}
}
impl Default for BorderBrush {
fn default() -> BorderBrush {
"#000000".into()
......
/// Represents the degree to which the corners of a Border are rounded.
#[derive(Default, Clone, Copy)]
pub struct BorderRadius(pub f64);
property!(
......