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

Merge branch '176-glutin-window-shell' into 'master'

Resolve "Glutin window shell"

Closes #176

See merge request redox-os/orbtk!111
parents d12dfba5 f5cab7fa
Pipeline #4699 failed with stages
in 1 minute and 40 seconds
......@@ -23,6 +23,17 @@
"preLaunchTask": "build-web",
"url": "http://localhost:8000",
},
{
"type": "lldb",
"request": "launch",
"name": "Widgets experimental",
"program": "${workspaceFolder}/target/debug/examples/widgets",
"cwd": "${workspaceFolder}",
"preLaunchTask": "build experimental",
"sourceLanguages": [
"rust"
]
},
{
"type": "lldb",
"request": "launch",
......
......@@ -21,6 +21,26 @@
},
"problemMatcher": []
},
{
"label": "build experimental",
"command": "cargo",
"type": "shell",
"args": [
"build",
"--examples=minimal",
"--features",
"experimental"
],
"presentation": {
"reveal": "always",
"panel": "new"
},
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": []
},
{
"label": "build debug",
"command": "cargo",
......
This diff is collapsed.
......@@ -33,6 +33,7 @@ dces = { git = "https://gitlab.redox-os.org/redox-os/dces-rust.git" }
[features]
debug = []
experimental = ["orbtk-shell/experimental", "orbtk-api/experimental"]
[workspace]
members = [
......
......@@ -18,4 +18,7 @@ orbtk-css-engine = { version = "0.1.0", path = "../css-engine" }
orbtk-shell = { version = "0.1.0", path = "../shell" }
orbtk-utils = { version = "0.1.0", path = "../utils" }
orbtk-tree = { version = "0.1.0", path= "../tree" }
orbtk-theme = { version = "0.1.0", path= "../theme" }
\ No newline at end of file
orbtk-theme = { version = "0.1.0", path= "../theme" }
[features]
experimental = []
\ No newline at end of file
......@@ -15,7 +15,6 @@ pub struct Global {
/// Stores the state of the keyboard
pub keyboard_state: KeyboardState,
}
#[derive(Default)]
......@@ -123,4 +122,4 @@ mod tests {
state.set_key_state(Key::Alt, false);
assert_eq!(state.is_alt_down(), false);
}
}
\ No newline at end of file
}
......@@ -8,7 +8,11 @@ use std::{
use dces::prelude::{Entity, World};
use crate::{prelude::*, shell::{ShellRunner, WindowBuilder}, tree::* };
use crate::{
prelude::*,
shell::{ShellRunner, WindowBuilder},
tree::*,
};
pub use self::global::*;
pub use self::window::*;
......@@ -53,23 +57,57 @@ impl Application {
tree.root = window;
}
let title = world.entity_component_manager().borrow_component::<Title>(window).unwrap().clone();
let resizeable = world.entity_component_manager().borrow_component::<Resizeable>(window).unwrap().clone();
let position = world.entity_component_manager().borrow_component::<Pos>(window).unwrap().clone();
let constraint = world.entity_component_manager().borrow_component::<Constraint>(window).unwrap().clone();
let title = world
.entity_component_manager()
.borrow_component::<Title>(window)
.unwrap()
.clone();
let resizeable = world
.entity_component_manager()
.borrow_component::<Resizeable>(window)
.unwrap()
.clone();
let position = world
.entity_component_manager()
.borrow_component::<Pos>(window)
.unwrap()
.clone();
let constraint = world
.entity_component_manager()
.borrow_component::<Constraint>(window)
.unwrap()
.clone();
world.entity_component_manager().register_component(window, Global::default());
world.entity_component_manager().register_component(window, Global::default());
world.entity_component_manager().register_component(window, Bounds::from((0.0, 0.0, constraint.width(), constraint.height())));
world
.entity_component_manager()
.register_component(window, Global::default());
world
.entity_component_manager()
.register_component(window, Global::default());
world.entity_component_manager().register_component(
window,
Bounds::from((0.0, 0.0, constraint.width(), constraint.height())),
);
let window_shell = Rc::new(RefCell::new(WindowBuilder::new(WindowAdapter {
root: window,
render_objects: render_objects.clone(),
layouts: layouts.clone(),
handlers: handlers.clone(),
states: states.clone(),
..Default::default()
}).title(&(title.0)[..]).bounds(Bounds::from((position.0.x, position.0.y, constraint.width(), constraint.height()))).resizeable(resizeable.0).build()));
let window_shell = Rc::new(RefCell::new(
WindowBuilder::new(WindowAdapter {
root: window,
render_objects: render_objects.clone(),
layouts: layouts.clone(),
handlers: handlers.clone(),
states: states.clone(),
..Default::default()
})
.title(&(title.0)[..])
.bounds(Bounds::from((
position.0.x,
position.0.y,
constraint.width(),
constraint.height(),
)))
.resizeable(resizeable.0)
.build(),
));
world.register_init_system(InitSystem {
shell: window_shell.clone(),
......@@ -127,9 +165,7 @@ impl Application {
.build();
self.runners.push(ShellRunner {
updater: Box::new(WorldWrapper {
world
}),
updater: Box::new(WorldWrapper { world }),
window_shell,
update,
running,
......
......@@ -33,9 +33,12 @@ impl shell::WindowAdapter for WindowAdapter {
}
fn mouse(&mut self, x: f64, y: f64) {
self.event_queue.register_event(MouseMoveEvent {
position: Point::new(x, y)
}, self.root)
self.event_queue.register_event(
MouseMoveEvent {
position: Point::new(x, y),
},
self.root,
)
}
fn mouse_event(&mut self, event: shell::MouseEvent) {
......@@ -61,18 +64,12 @@ impl shell::WindowAdapter for WindowAdapter {
fn key_event(&mut self, event: shell::KeyEvent) {
match event.state {
shell::ButtonState::Up => self.event_queue.register_event(
KeyUpEvent {
key: event.key
},
self.root,
),
shell::ButtonState::Down => self.event_queue.register_event(
KeyDownEvent {
key: event.key
},
self.root,
),
shell::ButtonState::Up => self
.event_queue
.register_event(KeyUpEvent { key: event.key }, self.root),
shell::ButtonState::Down => self
.event_queue
.register_event(KeyDownEvent { key: event.key }, self.root),
}
}
......
......@@ -43,7 +43,7 @@ pub trait KeyDownHandler: Sized + Widget {
/// Inserts a handler.
fn on_key_down<H: Fn(Key) -> bool + 'static>(self, handler: H) -> Self {
self.insert_handler(KeyDownEventHandler {
handler: Rc::new(handler)
handler: Rc::new(handler),
})
}
}
......@@ -7,7 +7,9 @@ use std::{
use dces::prelude::{Entity, EntityComponentManager};
use crate::{prelude::*, tree::Tree, utils::prelude::*};
use crate::shell::{FONT_MEASURE, FontMeasure};
#[cfg(not(feature = "experimental"))]
use crate::shell::{FontMeasure, FONT_MEASURE};
use super::Layout;
......@@ -51,7 +53,9 @@ impl Layout for FixedSizeLayout {
// -- todo will be removed after orbgl merge --
let size = widget.try_get::<Image>()
#[cfg(not(feature = "experimental"))]
let size = widget
.try_get::<Image>()
.map(|image| (image.width(), image.height()))
.or_else(|| {
widget.try_get::<Text>().and_then(|text| {
......@@ -59,29 +63,42 @@ impl Layout for FixedSizeLayout {
let font_size = widget.get::<FontSize>();
if text.0.is_empty() {
widget.try_get::<WaterMark>()
#[cfg(not(feature = "experimental"))]
widget
.try_get::<WaterMark>()
.filter(|water_mark| !water_mark.0.is_empty())
.map(|water_mark| FONT_MEASURE.measure(&water_mark.0, &(font.0).0, font_size.0 as u32))
.map(|water_mark| {
FONT_MEASURE.measure(&water_mark.0, &(font.0).0, font_size.0 as u32)
})
} else {
let mut size = FONT_MEASURE.measure(&text.0, &(font.0).0, font_size.0 as u32);
#[cfg(not(feature = "experimental"))]
let mut size =
FONT_MEASURE.measure(&text.0, &(font.0).0, font_size.0 as u32);
if text.0.ends_with(" ") {
size.0 += FONT_MEASURE.measure("a", &(font.0).0, font_size.0 as u32).0 / 2;
size.0 +=
FONT_MEASURE.measure("a", &(font.0).0, font_size.0 as u32).0 / 2;
}
Some(size)
}
})
})
.or_else(|| {
widget.try_get::<FontIcon>()
#[cfg(not(feature = "experimental"))]
widget
.try_get::<FontIcon>()
.filter(|font_icon| !font_icon.0.is_empty())
.map(|font_icon| FONT_MEASURE.measure(
&font_icon.0,
&(widget.get::<IconFont>().0).0,
widget.get::<IconSize>().0 as u32,
))
.map(|font_icon| {
FONT_MEASURE.measure(
&font_icon.0,
&(widget.get::<IconFont>().0).0,
widget.get::<IconSize>().0 as u32,
)
})
});
#[cfg(feature = "experimental")]
let size = Some((0.0, 0.0));
if let Some(size) = size {
if let Ok(constraint) = ecm.borrow_mut_component::<Constraint>(entity) {
......
......@@ -260,9 +260,9 @@ impl Layout for GridLayout {
let stretch_width = ((size.0 - used_width)
/ columns
.iter()
.filter(|column| column.width == ColumnWidth::Stretch)
.count() as f64)
.iter()
.filter(|column| column.width == ColumnWidth::Stretch)
.count() as f64)
.trunc();
columns
......@@ -324,9 +324,9 @@ impl Layout for GridLayout {
let stretch_height = ((size.1 - used_height)
/ rows
.iter()
.filter(|row| row.height == RowHeight::Stretch)
.count() as f64)
.iter()
.filter(|row| row.height == RowHeight::Stretch)
.count() as f64)
.trunc();
rows.iter_mut()
......@@ -428,11 +428,21 @@ impl Layout for GridLayout {
if let Ok(child_bounds) = ecm.borrow_mut_component::<Bounds>(*child) {
child_bounds.set_x(
cell_position.0
+ c_horizontal_alignment.align_position(size.0, available_size.0, c_margin.left(), c_margin.right()),
+ c_horizontal_alignment.align_position(
size.0,
available_size.0,
c_margin.left(),
c_margin.right(),
),
);
child_bounds.set_y(
cell_position.1
+ c_vertical_alignment.align_position(size.1, available_size.1, c_margin.top(), c_margin.bottom()),
+ c_vertical_alignment.align_position(
size.1,
available_size.1,
c_margin.top(),
c_margin.bottom(),
),
);
}
}
......
......@@ -151,20 +151,20 @@ impl Layout for PaddingLayout {
child_bounds.set_x(
padding.left()
+ child_horizontal_alignment.align_position(
available_size.0,
child_bounds.width(),
child_margin.left(),
child_margin.right(),
),
available_size.0,
child_bounds.width(),
child_margin.left(),
child_margin.right(),
),
);
child_bounds.set_y(
padding.top()
+ child_vertical_alignment.align_position(
available_size.1,
child_bounds.height(),
child_margin.top(),
child_margin.bottom(),
),
available_size.1,
child_bounds.height(),
child_margin.top(),
child_margin.bottom(),
),
);
}
}
......
......@@ -156,11 +156,11 @@ impl Layout for StackLayout {
child_bounds.set_x(
size_counter
+ child_horizontal_alignment.align_position(
available_size.0,
child_bounds.width(),
child_margin.left(),
child_margin.right(),
),
available_size.0,
child_bounds.width(),
child_margin.left(),
child_margin.right(),
),
);
child_bounds.set_y(child_vertical_alignment.align_position(
available_size.1,
......@@ -181,11 +181,11 @@ impl Layout for StackLayout {
child_bounds.set_y(
size_counter
+ child_vertical_alignment.align_position(
available_size.1,
child_bounds.height(),
child_margin.top(),
child_margin.bottom(),
),
available_size.1,
child_bounds.height(),
child_margin.top(),
child_margin.bottom(),
),
);
size_counter +=
child_bounds.height() + child_margin.top() + child_margin.bottom();
......@@ -203,4 +203,4 @@ impl Into<Box<dyn Layout>> for StackLayout {
fn into(self) -> Box<dyn Layout> {
Box::new(self)
}
}
\ No newline at end of file
}
......@@ -104,10 +104,17 @@ impl Layout for TextSelectionLayout {
let vertical_alignment = VerticalAlignment::get(entity, ecm);
let margin = Margin::get(entity, ecm);
#[cfg(not(feature = "experimental"))]
{
let mut widget = WidgetContainer::new(entity, ecm);
size.1 = vertical_alignment.align_measure(parent_size.1, size.1, margin.top(), margin.bottom());
size.1 = vertical_alignment.align_measure(
parent_size.1,
size.1,
margin.top(),
margin.bottom(),
);
if let Some(text) = widget.try_get::<Text>() {
let font = widget.get::<Font>();
......@@ -120,8 +127,10 @@ impl Layout for TextSelectionLayout {
.0 as f64;
if text_part.ends_with(" ") {
pos +=
(crate::shell::FONT_MEASURE.measure("a", &(font.0).0, font_size.0 as u32).0 / 2) as f64;
pos += (crate::shell::FONT_MEASURE
.measure("a", &(font.0).0, font_size.0 as u32)
.0
/ 2) as f64;
}
}
}
......
/*!
API crate that provides base api and elements for OrbTk like widgets basis.
*/
API crate that provides base api and elements for OrbTk like widgets basis.
*/
pub use dces::prelude::*;
pub use orbtk_css_engine::prelude as css_engine;
pub use orbtk_shell::prelude as shell;
pub use orbtk_theme::prelude as theme;
pub use orbtk_tree::prelude as tree;
pub use orbtk_utils::prelude as utils;
pub use orbtk_theme::prelude as theme;
pub mod application;
pub mod event;
pub mod layout;
pub mod prelude;
pub mod properties;
pub mod render_object;
pub mod systems;
pub mod widget;
pub mod prelude;
#[macro_use]
pub mod macros;
......@@ -9,7 +9,6 @@ pub use crate::{
property,
render_object::*,
systems::*,
widget::*,
widget,
widget::*,
};
......@@ -221,4 +221,3 @@ impl ColumnExt for Columns {
(self.0).0.iter_mut()
}
}
......@@ -3,4 +3,4 @@ use crate::prelude::*;
property!(
/// `ColumnSpan` describes the column span of a widget on the `Grid`.
ColumnSpan(usize)
);
\ No newline at end of file
);
......@@ -79,19 +79,17 @@ impl ConstraintBuilder {
/// Builds the constraint.
pub fn build(self) -> Constraint {
Constraint(
BoxConstraint {
width: self.width,
height: self.height,
min_width: self.min_width,
min_height: self.min_height,
max_width: self.max_width,
max_height: self.max_height,
})
Constraint(BoxConstraint {
width: self.width,
height: self.height,
min_width: self.min_width,
min_height: self.min_height,
max_width: self.max_width,
max_height: self.max_height,
})
}
}
/// `BoxConstraint` describes a box constraint.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct BoxConstraint {
......
......@@ -3,4 +3,4 @@ use crate::prelude::*;
property!(
/// `GridRow` describes the row position of a widget on the `Grid`.
GridRow(usize)
);
\ No newline at end of file
);
......@@ -15,4 +15,4 @@ impl From<(i32, i32)> for Pos {
fn from(s: (i32, i32)) -> Pos {
Pos::from((s.0 as f64, s.1 as f64))
}
}
\ No newline at end of file
}
......@@ -223,4 +223,3 @@ impl RowExt for Rows {
}
// --- Conversions ---
......@@ -3,4 +3,4 @@ use crate::prelude::*;
property!(
/// `RowSpan` describes the row span of a widget on the `Grid`.
RowSpan(usize)
);
\ No newline at end of file
);
......@@ -18,7 +18,7 @@ impl From<(&str)> for ScrollMode {
fn from(s: &str) -> ScrollMode {
match s {
"Auto" | "auto" => ScrollMode::Auto,
_ => ScrollMode::None
_ => ScrollMode::None,
}
}
}
\ No newline at end of file
}
......@@ -115,7 +115,6 @@ fn test_set_position() {
assert_eq!(7.0, bounds.y());
}
#[test]
fn test_from() {
let bounds = Bounds::from((9.0, 10.0, 11.0, 12.0));
......@@ -126,10 +125,12 @@ fn test_from() {
assert_eq!(12.0, bounds.height());
}
#[test]
fn test_into() {
let bounds: PropertySource<Bounds> = (17.0, 18.0, 19.0, 20.0).into();
assert_eq!(bounds, PropertySource::Value::<Bounds>(Bounds(Rect::new(17.0, 18.0, 19.0, 20.0))));
assert_eq!(
bounds,
PropertySource::Value::<Bounds>(Bounds(Rect::new(17.0, 18.0, 19.0, 20.0)))
);
}
......@@ -39,7 +39,10 @@ fn test_set_current_height() {
let max_height = 64.0;
let builder = RowBuilder::new();
let mut row = builder.min_height(min_height).max_height(max_height).build();
let mut row = builder
.min_height(min_height)
.max_height(max_height)
.build();
row.set_current_height(out_one_height);
assert_eq!(row.current_height(), min_height);
......
......@@ -17,8 +17,8 @@ mod widget;
/// Used to the a property of a widget.
pub fn get_property<T>(entity: Entity, ecm: &EntityComponentManager) -> T
where
T: Clone + Component + Default,
where
T: Clone + Component + Default,
{
ecm.borrow_component::<T>(entity)
.map(|r| r.clone())
......
......@@ -3,4 +3,4 @@ use crate::prelude::*;
property!(
/// `Focused` describes the focused (keyboard focus) state of a widget.
Focused(bool)
);
\ No newline at end of file
);
......@@ -3,4 +3,4 @@ use crate::prelude::*;
property!(
/// `MouseOver` describes the mouse over state of a widget.
MouseOver(bool)
);
\ No newline at end of file
);
......@@ -3,4 +3,4 @@ use crate::prelude::*;
property!(
/// `Pressed` describes the pressed (touch / mouse) state of a widget.
Pressed(bool)
);
\ No newline at end of file
);
......@@ -3,4 +3,4 @@ use crate::prelude::*;
property!(
/// `Selected` describes the selected state of a widget.
Selected(bool)
);
\ No newline at end of file
);
......@@ -9,4 +9,4 @@ impl From<i32> for BorderRadius {
fn from(s: i32) -> BorderRadius {
BorderRadius(s as f64)
}
}
\ No newline at end of file
}
......@@ -9,4 +9,4 @@ impl From<i32> for FontSize {
fn from(s: i32) -> FontSize {
FontSize(s as f64)
}
}
\ No newline at end of file
}
......@@ -2,7 +2,8 @@ use crate::{prelude::*, utils::*};
property!(
/// `IconBrush` describes the icon brush of a visual element.
IconBrush(Brush));
IconBrush(Brush)
);
// --- Conversions ---
......
......@@ -9,4 +9,4 @@ impl From<i32> for IconSize {
fn from(s: i32) -> IconSize {
IconSize(s as f64)
}
}
\ No newline at end of file
}
......@@ -9,4 +9,4 @@ impl From<i32> for Opacity {
fn from(s: i32) -> Opacity {