Skip to content

Commit

Permalink
Pretty much usable (there are missing functions such as remove and so…
Browse files Browse the repository at this point in the history
…, but I think the main parts are done (mainly parsing Style, returning Layout))
  • Loading branch information
adjabaev committed Aug 20, 2024
1 parent c1bb7a9 commit 21ec83d
Show file tree
Hide file tree
Showing 21 changed files with 1,424 additions and 736 deletions.
28 changes: 16 additions & 12 deletions bindings/java/java/com/dioxuslabs/taffy/Taffy.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
package com.dioxuslabs.taffy;

import com.dioxuslabs.taffy.geom.TaffyPoint;
import com.dioxuslabs.taffy.geom.TaffyRect;
import com.dioxuslabs.taffy.geom.measure.TaffyLengthPercentageAuto;
import com.dioxuslabs.taffy.style.TaffyOverflow;
import com.dioxuslabs.taffy.geom.TaffySize;
import com.dioxuslabs.taffy.geom.measure.TaffyLengthPercentage;
import com.dioxuslabs.taffy.style.TaffyStyle;
import com.dioxuslabs.taffy.tree.TaffyLayout;

class Taffy {
static {
System.loadLibrary("jtaffy");
}

public static void main(String[] args) {
TaffyTree tree = new TaffyTree();
System.out.println(tree.ptr);

long id = tree.newLeaf(TaffyStyle.builder()
.overflow(new TaffyPoint<>(TaffyOverflow.SCROLL, TaffyOverflow.HIDDEN))
.inset(new TaffyRect<>(TaffyLengthPercentageAuto.auto(), TaffyLengthPercentageAuto.length(1), TaffyLengthPercentageAuto.length(1), TaffyLengthPercentageAuto.length(1)))
TaffyTree taffy = new TaffyTree();
long node = taffy.newLeaf(TaffyStyle.builder()
.padding(new TaffyRect<>(
TaffyLengthPercentage.percentage(1f),
TaffyLengthPercentage.length(0f),
TaffyLengthPercentage.percentage(1f),
TaffyLengthPercentage.length(0f)
))
);

System.out.println("Leaf id: " + id);
taffy.computeLayout(node, TaffySize.definiteAvailableSize(200, 100));

int children = tree.childCount(id);
System.out.println("Getting the layout of nodes");

System.out.println("Child count: " + children);
TaffyLayout layout = taffy.layout(node);
System.out.println("Width: " + layout.size().width() + " = 200.0");
System.out.println("Height: " + layout.size().height() + " = 200.0");
}
}
25 changes: 25 additions & 0 deletions bindings/java/java/com/dioxuslabs/taffy/TaffyTree.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package com.dioxuslabs.taffy;

import com.dioxuslabs.taffy.geom.TaffySize;
import com.dioxuslabs.taffy.geom.measure.TaffyAvailableSpace;
import com.dioxuslabs.taffy.style.TaffyStyle;
import com.dioxuslabs.taffy.tree.TaffyLayout;

import java.util.List;

public class TaffyTree {
public final long ptr;
Expand All @@ -13,11 +18,31 @@ public long newLeaf(TaffyStyle style) {
return newLeaf(this.ptr, style);
}

public long newWithChildren(TaffyStyle style, List<Long> children) {
return newWithChildren(this.ptr, style, children);
}

public int childCount(long nodeId) {
return childCount(this.ptr, nodeId);
}

public void computeLayout(long node, TaffySize<TaffyAvailableSpace> availableSize) {
computeLayout(this.ptr, node, availableSize);
}

public TaffyLayout layout(long node) {
return layout(this.ptr, node);
}

private static native long newTaffyTree();

private static native long newLeaf(long pointer, TaffyStyle style);

private static native long newWithChildren(long pointer, TaffyStyle style, List<Long> children);

private static native int childCount(long pointer, long nodeId);

private static native void computeLayout(long pointer, long node, TaffySize<TaffyAvailableSpace> availableSize);

private static native TaffyLayout layout(long pointer, long node);
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions bindings/java/java/com/dioxuslabs/taffy/geom/TaffySize.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.dioxuslabs.taffy.geom;

import com.dioxuslabs.taffy.geom.measure.TaffyAvailableSpace;
import com.dioxuslabs.taffy.geom.measure.TaffyDimension;

/**
* The width and height of a {@link TaffyRect}
* @param width The x extent of the rectangle
Expand All @@ -9,4 +12,27 @@ public record TaffySize<T>(
T width,
T height
) {
public static TaffySize<TaffyDimension> lengthDimension(float width, float height) {
return new TaffySize<>(TaffyDimension.length(width), TaffyDimension.length(height));
}

public static TaffySize<TaffyDimension> percentDimension(float width, float height) {
return new TaffySize<>(TaffyDimension.percent(width), TaffyDimension.percent(height));
}

public static TaffySize<TaffyDimension> autoDimension() {
return new TaffySize<>(TaffyDimension.auto(), TaffyDimension.auto());
}

public static TaffySize<TaffyAvailableSpace> definiteAvailableSize(float width, float height) {
return new TaffySize<>(TaffyAvailableSpace.definite(width), TaffyAvailableSpace.definite(height));
}

public static TaffySize<TaffyAvailableSpace> minContentAvailableSize() {
return new TaffySize<>(TaffyAvailableSpace.minContent(), TaffyAvailableSpace.minContent());
}

public static TaffySize<TaffyAvailableSpace> maxContentAvailableSize() {
return new TaffySize<>(TaffyAvailableSpace.maxContent(), TaffyAvailableSpace.maxContent());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.dioxuslabs.taffy.geom.measure;

public class TaffyAvailableSpace {
private final byte type;
private final float value;

private TaffyAvailableSpace(byte type, float value) {
this.type = type;
this.value = value;
}

public static TaffyAvailableSpace definite(float value) {
return new TaffyAvailableSpace((byte) 0, value);
}

public static TaffyAvailableSpace minContent() {
return new TaffyAvailableSpace((byte) 1, 0);
}

public static TaffyAvailableSpace maxContent() {
return new TaffyAvailableSpace((byte) 2, 0);
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof TaffyAvailableSpace as)) {
return false;
}
return type == as.type && value == as.value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,11 @@ public enum TaffyAlignContent {
* The gap between the first and last items is exactly <b>HALF</b> the gap between items.
* The gaps are distributed evenly in proportion to these ratios.
*/
SPACE_AROUND
SPACE_AROUND;

private final int internal;

TaffyAlignContent() {
internal = ordinal();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,11 @@ public enum TaffyAlignItems {
/**
* Stretch to fill the container
*/
STRETCH
STRETCH;

private final int internal;

TaffyAlignItems() {
internal = ordinal();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,11 @@ public enum TaffyFlexDirection {
* <p>
* Items will be added from bottom to top in a column.
*/
COLUMN_REVERSE
COLUMN_REVERSE;

private final int internal;

TaffyFlexDirection() {
internal = ordinal();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,11 @@ public enum TaffyFlexWrap {
/**
* Items will wrap in the opposite direction to this item's {@link TaffyFlexDirection}
*/
WRAP_REVERSE
WRAP_REVERSE;

private final int internal;

TaffyFlexWrap() {
internal = ordinal();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,11 @@ public enum TaffyGridAutoFlow {
/**
* Combines COLUMN with the dense packing algorithm.
*/
COLUMN_DENSE
COLUMN_DENSE;

private final int internal;

TaffyGridAutoFlow() {
internal = ordinal();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,11 @@ public enum TaffyPosition {
* <p>
* WARNING: to opt-out of layouting entirely, you must use {@link TaffyDisplay#NONE} instead on your {@link TaffyStyle} object.
*/
ABSOLUTE
ABSOLUTE;

private final int internal;

TaffyPosition() {
internal = ordinal();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,11 @@ public enum TaffyTextAlign {
/**
* Corresponds to `-webkit-center` or `-moz-center` in browsers
*/
LEGACY_CENTER
LEGACY_CENTER;

private final int internal;

TaffyTextAlign() {
internal = ordinal();
}
}
34 changes: 34 additions & 0 deletions bindings/java/java/com/dioxuslabs/taffy/tree/TaffyLayout.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.dioxuslabs.taffy.tree;

import com.dioxuslabs.taffy.geom.TaffyPoint;
import com.dioxuslabs.taffy.geom.TaffyRect;
import com.dioxuslabs.taffy.geom.TaffySize;

/**
* The final result of a layout algorithm for a single node.
* @param order The relative ordering of the node
* <p>
* Nodes with a higher order should be rendered on top of those with a lower order. This is
* effectively a topological sort of each tree.
* @param location The top-left corner of the node
* @param size The width and height of the node
* @param contentSize The width and height of the content inside the node. This may be larger than the size
* of the node in the case of overflowing content and is useful for computing a "scroll
* width/height" for scrollable nodes
* @param scrollbarSize The size of the scrollbars in each dimension. If there is no scrollbar then the
* size will be zero.
* @param border The size of the borders of the node
* @param padding The size of the padding of the node
* @param margin The size of the margin of the node
*/
public record TaffyLayout(
int order,
TaffyPoint<Float> location,
TaffySize<Float> size,
TaffySize<Float> contentSize,
TaffySize<Float> scrollbarSize,
TaffyRect<Float> border,
TaffyRect<Float> padding,
TaffyRect<Float> margin
) {
}
55 changes: 55 additions & 0 deletions bindings/java/src/collections.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use std::convert::TryInto;
use jni::JNIEnv;
use jni::objects::{JObject, JValue, JValueOwned};
use crate::conversions::f_get_value;

/// Unwraps a Java List into a Rust Vec
pub unsafe fn get_list<'local, T, F>(env: &mut JNIEnv<'local>, value: JValueOwned<'local>, f: F) -> Vec<T>
where
F: Fn(&mut JNIEnv<'local>, JValueOwned<'local>) -> Option<T>,
{
let jlist_object = value.l().unwrap();

if jlist_object.is_null() {
return Vec::with_capacity(0);
}

let list = env.get_list(&jlist_object).unwrap();

let jlist_size = env
.call_method(&list, "size", "()I", &[])
.expect("Couldn't call size on List")
.i()
.unwrap();

let mut vec: Vec<T> = Vec::new();
for i in 0..jlist_size {
let element = env.call_method(&list, "get", "(I)Ljava/lang/Object;", &[JValue::Int(i)]).unwrap();

let value = f(env, element);
if value.is_some() {
vec.push(value.unwrap());
}
}

vec
}

/// Unwraps a Java List into a Rust array, it basically uses `unwrap_jlist` and then tries to convert the Vec into an array
#[allow(dead_code)]
pub unsafe fn get_array<'local, T, F, const N: usize>(env: &mut JNIEnv<'local>, value: JValueOwned<'local>, f: F) -> [T; N]
where
F: Fn(&mut JNIEnv<'local>, JValueOwned<'local>) -> Option<T>,
{
let vec = get_list(env, value, f);
vec.try_into()
.unwrap_or_else(|v: Vec<T>| panic!("Expected a Vec of length {} but it was {}", N, v.len()))
}

pub unsafe fn f_get_list<'local, T, F>(env: &mut JNIEnv<'local>, base: &JObject<'local>, field: &str, f: F) -> Vec<T>
where
F: Fn(&mut JNIEnv<'local>, JValueOwned<'local>) -> Option<T>,
{
let value = f_get_value(env, base, field, "Ljava/util/List;");
get_list(env, value, f)
}
Loading

0 comments on commit 21ec83d

Please sign in to comment.