Skip to content

Commit

Permalink
[WIP]: Text wrapping
Browse files Browse the repository at this point in the history
  • Loading branch information
Saito Nakamura committed Feb 10, 2019
1 parent 47e7b19 commit 15a26df
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 21 deletions.
5 changes: 5 additions & 0 deletions examples/Examples.re
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ let state: state = {
render: w => TodoExample.render(w),
source: "TodoExample.re",
},
{
name: "Text",
render: _w => TextExample.render()},
source: "TextExample.re",
}
],
selectedExample: "Animation",
};
Expand Down
45 changes: 45 additions & 0 deletions examples/TextExample.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
open Revery.UI;
open Revery.Core;

module SomeText = {
let component = React.component("Example");

let make = () => {
component(slots => {
let (_focused, _setFocus, _slots: React.Hooks.empty) =
React.Hooks.state(false, slots);

let textContent = "All work and no play makes Jack a dull boy";

<Text
logging=true
style=Style.[
color(Colors.white),
fontFamily("Roboto-Regular.ttf"),
fontSize(20),
lineHeight(20.),
textWrap(TextWrapping.WhitespaceWrap),
width(200),
border(~color=Colors.blueViolet, ~width=5)
]
text=textContent
/>;
})
}

let createElement = (~children as _, ()) =>
React.element(make());
}

let render = () => <View
style=Style.[
position(`Absolute),
justifyContent(`Center),
alignItems(`Center),
bottom(0),
top(0),
left(0),
right(0),
]>
<SomeText />
</View>;
2 changes: 2 additions & 0 deletions src/Core/Revery_Core.re
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ module Events = Events;
module Performance = Performance;
module UniqueId = UniqueId;

module TextWrapping = TextWrapping

/*
* Internally exposed modules, just for testing.
*/
Expand Down
81 changes: 81 additions & 0 deletions src/Core/TextWrapping.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
type wrapType =
| NoWrap
| WhitespaceWrap;

let splitByWhitespace = text => {
let (_a, _) =
text
|> Str.split(Str.regexp("[ \n\r\x0c\t]+"))
|> List.fold_left(
((splitted, runningSumOffset), cur) => {
/* TODO is it? */
let whitespaceWidth = 1;
let currentRunningSumOffset =
runningSumOffset + String.length(cur) + whitespaceWidth;

(
[(cur, currentRunningSumOffset), ...splitted],
currentRunningSumOffset,
);
},
([], 0),
);
_a;
};

let wrapText = (~logging=false, ~text, ~measureWidth, ~maxWidth, ~isWrappingPoint) => {
let currWidth = ref(0);
let currOffset = ref(0);
let currLineOffset = ref(0);
let currLineNumber = ref(0);
let maxWidthLine = ref(0);
let lines: ref(list(string)) = ref([]);

String.iteri((i, ch) => {
let a = isWrappingPoint(Char.escaped(ch));
let isEnd = i == String.length(text) - 1;

if (logging) {
print_endline("TextNode:: iter:: char: " ++ Char.escaped(ch) ++ ", i: " ++ string_of_int(i));
print_endline("TextNode:: iter:: currOffset: " ++ string_of_int(currOffset^) ++ ", currLineOffset: " ++ string_of_int(currLineOffset^));
}

if (a || isEnd) {
let word = String.sub(text, currOffset^, i - currOffset^ + 1);
let dWidth = measureWidth(word);

if (logging)
print_endline("TextNode:: iter:: word: " ++ word ++ ", width: " ++ string_of_int(dWidth));

if ((currWidth^ + dWidth) >= maxWidth || isEnd) {
let line = if (isEnd)
String.sub(text, currLineOffset^, String.length(text) - currLineOffset^)
else
String.sub(text, currLineOffset^, currOffset^ - currLineOffset^ - 1)

if (logging)
print_endline("TextNode:: line: " ++ line);

lines := [line, ...lines^];
currLineNumber := currLineNumber^ + 1;
currLineOffset := currLineOffset^ + currOffset^ - currLineOffset^ - 1;
currWidth := 0;

if (maxWidthLine^ < currWidth^) {
maxWidthLine:= currWidth^;
();
} else {
();
}
} else {
currOffset := currOffset^ + String.length(word);
currWidth := currWidth^ + dWidth;
();
}
} else {
();
}
}, text);

(lines^, maxWidthLine^);
}
5 changes: 4 additions & 1 deletion src/UI/Node.re
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class node ('a) (()) = {
val _children: ref(list(node('a))) = ref([]);
val _style: ref(Style.t) = ref(Style.defaultStyle);
val _events: ref(NodeEvents.t(node('a))) = ref(NodeEvents.make());
val _logging: ref(bool) = ref(false);
val _layoutNode = ref(Layout.createNode([||], Layout.defaultStyle));
val _parent: ref(option(node('a))) = ref(None);
val _internalId: int = UniqueId.getUniqueId();
Expand Down Expand Up @@ -63,6 +64,8 @@ class node ('a) (()) = {
pub getStyle = () => _style^;
pub setEvents = events => _events := events;
pub getEvents = () => _events^;
pub setLogging = logging => _logging := logging;
pub getLogging = () => _logging^;
pub getWorldTransform = () => {
let state = _cachedNodeState^ |> getOrThrow("getWorldTransform");
state.worldTransform;
Expand Down Expand Up @@ -206,7 +209,7 @@ class node ('a) (()) = {
m,
)
};

_layoutNode := node;
node;
};
Expand Down
5 changes: 5 additions & 0 deletions src/UI/Primitives.re
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ module Text = {
~ref=?,
~style=emptyTextStyle,
~text="",
~logging=false,
children,
) =>
component((_: UiReact.Hooks.empty) =>
Expand All @@ -128,6 +129,7 @@ module Text = {
let node = (new TextNode.textNode)(text);
node#setEvents(events);
node#setStyle(styles);
node#setLogging(logging);
Obj.magic(node);
},
configureInstance: (~isFirstRender as _, node) => {
Expand All @@ -147,6 +149,7 @@ module Text = {
tn#setEvents(events);
tn#setStyle(styles);
tn#setText(text);
tn#setLogging(logging);
node;
},
children,
Expand All @@ -162,6 +165,7 @@ module Text = {
~ref=?,
~style=emptyTextStyle,
~text="",
~logging=false,
~children,
(),
) =>
Expand All @@ -174,6 +178,7 @@ module Text = {
~ref?,
~style,
~text,
~logging,
UiReact.listToElement(children),
),
);
Expand Down
19 changes: 17 additions & 2 deletions src/UI/Style.re
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ type t = {
right: int,
fontFamily,
fontSize: int,
lineHeight: float,
textWrap: TextWrapping.wrapType,
marginTop: int,
marginLeft: int,
marginRight: int,
Expand Down Expand Up @@ -93,6 +95,8 @@ let make =
~right=Encoding.cssUndefined,
~fontFamily="",
~fontSize=Encoding.cssUndefined,
~lineHeight=0.,
~textWrap=TextWrapping.NoWrap,
~marginTop=Encoding.cssUndefined,
~marginLeft=Encoding.cssUndefined,
~marginRight=Encoding.cssUndefined,
Expand Down Expand Up @@ -146,6 +150,8 @@ let make =
right,
fontFamily,
fontSize,
lineHeight,
textWrap,
transform,
marginTop,
marginLeft,
Expand Down Expand Up @@ -283,17 +289,22 @@ type coreStyleProps = [
| `Cursor(option(MouseCursors.t))
];



type fontProps = [ | `FontFamily(string) | `FontSize(int)];

type textProps = [ | `LineHeight(float) | `TextWrap(TextWrapping.wrapType)]

/*
Text and View props take different style properties as such
these nodes are typed to only allow styles to be specified
which are relevant to each
*/
type textStyleProps = [ fontProps | coreStyleProps];
type textStyleProps = [ textProps | fontProps | coreStyleProps];
type viewStyleProps = [ coreStyleProps];
type imageStyleProps = [ coreStyleProps];

type allProps = [ coreStyleProps | fontProps];
type allProps = [ coreStyleProps | fontProps | textProps];

let emptyTextStyle: list(textStyleProps) = [];
let emptyViewStyle: list(viewStyleProps) = [];
Expand Down Expand Up @@ -335,6 +346,8 @@ let top = f => `Top(f);

let fontSize = f => `FontSize(f);
let fontFamily = f => `FontFamily(f);
let lineHeight = h => `LineHeight(h);
let textWrap = w => `TextWrap(w);

let height = h => `Height(h);
let width = w => `Width(w);
Expand Down Expand Up @@ -472,6 +485,8 @@ let applyStyle = (style, styleRule) =>
| `Transform(transform) => {...style, transform}
| `FontFamily(fontFamily) => {...style, fontFamily}
| `FontSize(fontSize) => {...style, fontSize}
| `LineHeight(lineHeight) => {...style, lineHeight}
| `TextWrap(textWrap) => {...style, textWrap}
| `Cursor(cursor) => {...style, cursor}
| `Color(color) => {...style, color}
| `BackgroundColor(backgroundColor) => {...style, backgroundColor}
Expand Down

0 comments on commit 15a26df

Please sign in to comment.