Skip to content

Commit

Permalink
Implement new rust API for bindings and release v0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
Emil Sjölander committed Jul 5, 2019
1 parent a149c6b commit bce89b1
Show file tree
Hide file tree
Showing 35 changed files with 2,664 additions and 1,739 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "stretch"
version = "0.2.2"
version = "0.3.2"
authors = ["Emil Sjölander <[email protected]>"]
edition = "2018"
include = ["src/**/*", "Cargo.toml"]
Expand Down
53 changes: 29 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,32 +32,36 @@ Stretch is built in Rust but comes with bindings to multiple languages and platf
# Cargo.toml

[dependencies]
stretch = "0.2.2"
stretch = "0.3.2"
```

```rust
// main.rs

use stretch::geometry::Size;
use stretch::style::*;
use stretch::node::*;
use stretch::result::*;

fn main() {
let node = Node::new(
Style {
size: Size { width: Dimension::Points(100.0), height: Dimension::Points(100.0) },
justify_content: JustifyContent::Center,
..Default::default()
},
vec![&Node::new(
Style { size: Size { width: Dimension::Percent(0.5), height: Dimension::Auto }, ..Default::default() },
vec![],
)],
);

let layout = node.compute_layout(Size::undefined()).unwrap();
dbg!(layout);

fn main() -> Result<(), stretch::Error> {
let mut stretch = stretch::node::Stretch::new();

let child = stretch.new_node(
Style { size: Size { width: Dimension::Percent(0.5), height: Dimension::Auto }, ..Default::default() },
vec![],
)?;

let node = stretch.new_node(
Style {
size: Size { width: Dimension::Points(100.0), height: Dimension::Points(100.0) },
justify_content: JustifyContent::Center,
..Default::default()
},
vec![child],
)?;

stretch.compute_layout(node, Size::undefined())?;
dbg!(stretch.layout(node)?);
}

```

### Android
Expand All @@ -73,7 +77,7 @@ android {
}
dependencies {
implementation 'app.visly.stretch:stretch:0.2.2'
implementation 'app.visly.stretch:stretch:0.3.2'
}
```

Expand All @@ -94,7 +98,7 @@ Log.d(TAG, "width: ${layout.width}, height: ${layout.height}")
```ruby
# Podfile

pod 'StretchKit', '~> 0.2.2'
pod 'StretchKit', '~> 0.3.2'
```

```swift
Expand All @@ -118,10 +122,11 @@ print("width: \(layout.width), height: \(layout.height)")
```javascript
// index.js

import { Node, JustifyContent } from 'stretch-layout';
import { Allocator, Node, JustifyContent } from 'stretch-layout';

const node = new Node({width: 100, height: 100, justifyContent: JustifyContent.Center});
node.addChild(new Node({width: '50%', height: '50%'}));
const allocator = new Allocator();
const node = new Node(allocator, {width: 100, height: 100, justifyContent: JustifyContent.Center});
node.addChild(new Node(allocator, {width: '50%', height: '50%'}));
const layout = node.computeLayout();

console.log(layout.width, layout.height);
Expand Down
2 changes: 1 addition & 1 deletion StretchKit.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'StretchKit'
s.version = '0.2.2'
s.version = '0.3.2'
s.summary = 'Swift bindings for the Stretch layout engine.'
s.description = "A high performance & cross-platform layout engine."
s.homepage = 'https://visly.app/stretch'
Expand Down
4 changes: 2 additions & 2 deletions bindings/js/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "stretch-layout"
version = "0.2.2"
version = "0.3.2"
authors = ["Visly Inc. <[email protected]>"]
edition = "2018"

Expand All @@ -13,7 +13,7 @@ default = ["console_error_panic_hook"]
[dependencies]
wasm-bindgen = "0.2"
js-sys = "0.3"
stretch = "0.2.2"
stretch = "0.3.2"

# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
Expand Down
122 changes: 80 additions & 42 deletions bindings/js/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

mod utils;

use std::cell::RefCell;
use std::rc::Rc;

use js_sys::Function;
use js_sys::Reflect;
use wasm_bindgen::prelude::*;
Expand Down Expand Up @@ -363,14 +366,18 @@ pub struct Layout {

#[wasm_bindgen]
impl Layout {
fn new(layout: stretch::result::Layout) -> Layout {
fn new(allocator: &Allocator, node: stretch::node::Node) -> Layout {
let stretch = allocator.stretch.borrow();
let layout = stretch.layout(node).unwrap();
let children = stretch.children(node).unwrap();

Layout {
width: layout.size.width,
height: layout.size.height,
x: layout.location.x,
y: layout.location.y,
childCount: layout.children.len(),
children: layout.children.into_iter().map(Layout::new).collect(),
childCount: children.len(),
children: children.into_iter().map(|child| Layout::new(allocator, child)).collect(),
}
}

Expand All @@ -380,8 +387,23 @@ impl Layout {
}
}

#[wasm_bindgen]
#[derive(Clone)]
pub struct Allocator {
stretch: Rc<RefCell<stretch::node::Stretch>>,
}

#[wasm_bindgen]
impl Allocator {
#[wasm_bindgen(constructor)]
pub fn new() -> Allocator {
Allocator { stretch: Rc::new(RefCell::new(stretch::node::Stretch::new())) }
}
}

#[wasm_bindgen]
pub struct Node {
allocator: Allocator,
node: stretch::node::Node,
style: JsValue,

Expand All @@ -392,60 +414,72 @@ pub struct Node {
#[wasm_bindgen]
impl Node {
#[wasm_bindgen(constructor)]
pub fn new(style: &JsValue) -> Node {
Node { node: stretch::node::Node::new(parse_style(&style), vec![]), style: style.clone(), childCount: 0 }
pub fn new(allocator: &Allocator, style: &JsValue) -> Node {
Node {
allocator: allocator.clone(),
node: allocator.stretch.borrow_mut().new_node(parse_style(&style), vec![]).unwrap(),
style: style.clone(),
childCount: 0,
}
}

#[wasm_bindgen(js_name = setMeasure)]
pub fn set_measure(&mut self, measure: &JsValue) {
let measure = Function::from(measure.clone());

self.node.set_measure(Some(Box::new(move |constraints| {
let widthConstraint = if let stretch::number::Number::Defined(val) = constraints.width {
val.into()
} else {
JsValue::UNDEFINED
};

let heightConstaint = if let stretch::number::Number::Defined(val) = constraints.height {
val.into()
} else {
JsValue::UNDEFINED
};

if let Ok(result) = measure.call2(&JsValue::UNDEFINED, &widthConstraint, &heightConstaint) {
let width = get_f32(&result, "width");
let height = get_f32(&result, "height");

if width.is_some() && height.is_some() {
return Ok(stretch::geometry::Size { width: width.unwrap(), height: height.unwrap() });
}
}
self.allocator
.stretch
.borrow_mut()
.set_measure(
self.node,
Some(Box::new(move |constraints| {
let widthConstraint = if let stretch::number::Number::Defined(val) = constraints.width {
val.into()
} else {
JsValue::UNDEFINED
};

let heightConstaint = if let stretch::number::Number::Defined(val) = constraints.height {
val.into()
} else {
JsValue::UNDEFINED
};

if let Ok(result) = measure.call2(&JsValue::UNDEFINED, &widthConstraint, &heightConstaint) {
let width = get_f32(&result, "width");
let height = get_f32(&result, "height");

if width.is_some() && height.is_some() {
return Ok(stretch::geometry::Size { width: width.unwrap(), height: height.unwrap() });
}
}

Err(Box::new("Failed in javascript"))
})));
Err(Box::new("Failed in javascript"))
})),
)
.unwrap();
}

#[wasm_bindgen(js_name = addChild)]
pub fn add_child(&mut self, child: &Node) {
self.node.add_child(&child.node);
self.allocator.stretch.borrow_mut().add_child(self.node, child.node).unwrap();
self.childCount += 1;
}

#[wasm_bindgen(js_name = removeChild)]
pub fn remove_child(&mut self, child: &Node) {
self.node.remove_child(&child.node);
self.allocator.stretch.borrow_mut().remove_child(self.node, child.node).unwrap();
self.childCount -= 1;
}

#[wasm_bindgen(js_name = replaceChildAtIndex)]
pub fn replace_child_at_index(&mut self, index: usize, child: &Node) {
self.node.replace_child_at_index(index, &child.node);
self.allocator.stretch.borrow_mut().replace_child_at_index(self.node, index, child.node).unwrap();
}

#[wasm_bindgen(js_name = removeChildAtIndex)]
pub fn remove_child_at_index(&mut self, index: usize) {
self.node.remove_child_at_index(index);
self.allocator.stretch.borrow_mut().remove_child_at_index(self.node, index).unwrap();
self.childCount -= 1;
}

Expand All @@ -456,25 +490,28 @@ impl Node {

#[wasm_bindgen(js_name = setStyle)]
pub fn set_style(&mut self, style: &JsValue) {
self.node.set_style(parse_style(style));
self.allocator.stretch.borrow_mut().set_style(self.node, parse_style(style)).unwrap();
self.style = style.clone();
}

#[wasm_bindgen(js_name = markDirty)]
pub fn mark_dirty(&mut self) {
self.node.mark_dirty()
self.allocator.stretch.borrow_mut().mark_dirty(self.node).unwrap()
}

#[wasm_bindgen(js_name = isDirty)]
pub fn is_dirty(&self) -> bool {
self.node.dirty()
self.allocator.stretch.borrow().dirty(self.node).unwrap()
}

#[wasm_bindgen(js_name = computeLayout)]
pub fn compute_layout(&self, size: &JsValue) -> Layout {
Layout::new(
self.node
.compute_layout(stretch::geometry::Size {
pub fn compute_layout(&mut self, size: &JsValue) -> Layout {
self.allocator
.stretch
.borrow_mut()
.compute_layout(
self.node,
stretch::geometry::Size {
width: if let Some(val) = get_f32(size, "width") {
stretch::number::Number::Defined(val)
} else {
Expand All @@ -485,9 +522,10 @@ impl Node {
} else {
stretch::number::Number::Undefined
},
})
.unwrap(),
)
},
)
.unwrap();
Layout::new(&self.allocator, self.node)
}
}

Expand Down
Loading

0 comments on commit bce89b1

Please sign in to comment.