react-x11 0.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +226 -0
- package/package.json +60 -7
- package/src/ClickToComponent.js +179 -0
- package/src/DevToolsIntegration.js +106 -0
- package/src/Reconciler.js +507 -0
- package/src/components/Button.js +63 -0
- package/src/components/Canvas3D.js +28 -0
- package/src/components/Checkbox.js +69 -0
- package/src/components/Dialog.js +138 -0
- package/src/components/Menu.js +644 -0
- package/src/components/ProgressBar.js +48 -0
- package/src/components/Radio.js +95 -0
- package/src/components/Select.js +272 -0
- package/src/components/Slider.js +177 -0
- package/src/components/Switch.js +49 -0
- package/src/components/Tooltip.js +146 -0
- package/src/components/anchor.js +211 -0
- package/src/components/index.js +17 -0
- package/src/components/keys.js +21 -0
- package/src/components/theme.js +66 -0
- package/src/components/typeahead.js +56 -0
- package/src/events.js +584 -0
- package/src/geometry3d.js +223 -0
- package/src/glnodes.js +275 -0
- package/src/index.js +30 -0
- package/src/mat4.js +235 -0
- package/src/nodes.js +1985 -0
- package/src/pointer3d.js +158 -0
- package/src/priority.js +39 -0
- package/src/raycast3d.js +146 -0
- package/src/richnodes.js +436 -0
- package/src/scene3d.js +683 -0
- package/src/styles.js +189 -0
- package/.npmignore +0 -17
- package/combobox.jsx +0 -69
- package/react-x11.js +0 -119
- package/test-canvas.js +0 -98
package/src/styles.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// Style props → yoga setters (layout) and paint metadata. Flat, ink-style
|
|
2
|
+
// props: <box flexDirection="row" padding={8} backgroundColor="#eee">.
|
|
3
|
+
// Numbers are pixels; strings like '50%' / 'auto' pass through to yoga.
|
|
4
|
+
// Yoga comes from ntk (>= 3.1.0) so renderer and ntk widgets share one
|
|
5
|
+
// WASM instance and enum set.
|
|
6
|
+
import { Yoga } from 'ntk';
|
|
7
|
+
|
|
8
|
+
export { Yoga };
|
|
9
|
+
|
|
10
|
+
const FLEX_DIRECTION = {
|
|
11
|
+
row: Yoga.FLEX_DIRECTION_ROW,
|
|
12
|
+
'row-reverse': Yoga.FLEX_DIRECTION_ROW_REVERSE,
|
|
13
|
+
column: Yoga.FLEX_DIRECTION_COLUMN,
|
|
14
|
+
'column-reverse': Yoga.FLEX_DIRECTION_COLUMN_REVERSE,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const JUSTIFY = {
|
|
18
|
+
'flex-start': Yoga.JUSTIFY_FLEX_START,
|
|
19
|
+
center: Yoga.JUSTIFY_CENTER,
|
|
20
|
+
'flex-end': Yoga.JUSTIFY_FLEX_END,
|
|
21
|
+
'space-between': Yoga.JUSTIFY_SPACE_BETWEEN,
|
|
22
|
+
'space-around': Yoga.JUSTIFY_SPACE_AROUND,
|
|
23
|
+
'space-evenly': Yoga.JUSTIFY_SPACE_EVENLY,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const ALIGN = {
|
|
27
|
+
auto: Yoga.ALIGN_AUTO,
|
|
28
|
+
'flex-start': Yoga.ALIGN_FLEX_START,
|
|
29
|
+
center: Yoga.ALIGN_CENTER,
|
|
30
|
+
'flex-end': Yoga.ALIGN_FLEX_END,
|
|
31
|
+
stretch: Yoga.ALIGN_STRETCH,
|
|
32
|
+
baseline: Yoga.ALIGN_BASELINE,
|
|
33
|
+
'space-between': Yoga.ALIGN_SPACE_BETWEEN,
|
|
34
|
+
'space-around': Yoga.ALIGN_SPACE_AROUND,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const FLEX_WRAP = {
|
|
38
|
+
nowrap: Yoga.WRAP_NO_WRAP,
|
|
39
|
+
wrap: Yoga.WRAP_WRAP,
|
|
40
|
+
'wrap-reverse': Yoga.WRAP_WRAP_REVERSE,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const POSITION = {
|
|
44
|
+
static: Yoga.POSITION_TYPE_STATIC,
|
|
45
|
+
relative: Yoga.POSITION_TYPE_RELATIVE,
|
|
46
|
+
absolute: Yoga.POSITION_TYPE_ABSOLUTE,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const DISPLAY = {
|
|
50
|
+
flex: Yoga.DISPLAY_FLEX,
|
|
51
|
+
none: Yoga.DISPLAY_NONE,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const OVERFLOW = {
|
|
55
|
+
visible: Yoga.OVERFLOW_VISIBLE,
|
|
56
|
+
hidden: Yoga.OVERFLOW_HIDDEN,
|
|
57
|
+
scroll: Yoga.OVERFLOW_SCROLL,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const pick = (map, value, name) => {
|
|
61
|
+
if (value === undefined) return undefined;
|
|
62
|
+
if (!(value in map)) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`react-x11: invalid ${name} "${value}" (expected one of ${Object.keys(map).join(', ')})`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return map[value];
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Each entry: prop name -> (yogaNode, value) applier. `undefined` resets.
|
|
71
|
+
const LAYOUT_APPLIERS = {
|
|
72
|
+
width: (n, v) => n.setWidth(v),
|
|
73
|
+
height: (n, v) => n.setHeight(v),
|
|
74
|
+
minWidth: (n, v) => n.setMinWidth(v),
|
|
75
|
+
minHeight: (n, v) => n.setMinHeight(v),
|
|
76
|
+
maxWidth: (n, v) => n.setMaxWidth(v),
|
|
77
|
+
maxHeight: (n, v) => n.setMaxHeight(v),
|
|
78
|
+
flexDirection: (n, v) =>
|
|
79
|
+
n.setFlexDirection(
|
|
80
|
+
pick(FLEX_DIRECTION, v, 'flexDirection') ?? Yoga.FLEX_DIRECTION_COLUMN,
|
|
81
|
+
),
|
|
82
|
+
justifyContent: (n, v) =>
|
|
83
|
+
n.setJustifyContent(
|
|
84
|
+
pick(JUSTIFY, v, 'justifyContent') ?? Yoga.JUSTIFY_FLEX_START,
|
|
85
|
+
),
|
|
86
|
+
alignItems: (n, v) =>
|
|
87
|
+
n.setAlignItems(pick(ALIGN, v, 'alignItems') ?? Yoga.ALIGN_STRETCH),
|
|
88
|
+
alignSelf: (n, v) =>
|
|
89
|
+
n.setAlignSelf(pick(ALIGN, v, 'alignSelf') ?? Yoga.ALIGN_AUTO),
|
|
90
|
+
alignContent: (n, v) =>
|
|
91
|
+
n.setAlignContent(pick(ALIGN, v, 'alignContent') ?? Yoga.ALIGN_FLEX_START),
|
|
92
|
+
flexWrap: (n, v) =>
|
|
93
|
+
n.setFlexWrap(pick(FLEX_WRAP, v, 'flexWrap') ?? Yoga.WRAP_NO_WRAP),
|
|
94
|
+
flexGrow: (n, v) => n.setFlexGrow(v ?? 0),
|
|
95
|
+
flexShrink: (n, v) => n.setFlexShrink(v ?? 1),
|
|
96
|
+
flexBasis: (n, v) => n.setFlexBasis(v),
|
|
97
|
+
position: (n, v) =>
|
|
98
|
+
n.setPositionType(
|
|
99
|
+
pick(POSITION, v, 'position') ?? Yoga.POSITION_TYPE_RELATIVE,
|
|
100
|
+
),
|
|
101
|
+
top: (n, v) => n.setPosition(Yoga.EDGE_TOP, v),
|
|
102
|
+
right: (n, v) => n.setPosition(Yoga.EDGE_RIGHT, v),
|
|
103
|
+
bottom: (n, v) => n.setPosition(Yoga.EDGE_BOTTOM, v),
|
|
104
|
+
left: (n, v) => n.setPosition(Yoga.EDGE_LEFT, v),
|
|
105
|
+
margin: (n, v) => n.setMargin(Yoga.EDGE_ALL, v),
|
|
106
|
+
marginTop: (n, v) => n.setMargin(Yoga.EDGE_TOP, v),
|
|
107
|
+
marginRight: (n, v) => n.setMargin(Yoga.EDGE_RIGHT, v),
|
|
108
|
+
marginBottom: (n, v) => n.setMargin(Yoga.EDGE_BOTTOM, v),
|
|
109
|
+
marginLeft: (n, v) => n.setMargin(Yoga.EDGE_LEFT, v),
|
|
110
|
+
padding: (n, v) => n.setPadding(Yoga.EDGE_ALL, v),
|
|
111
|
+
paddingTop: (n, v) => n.setPadding(Yoga.EDGE_TOP, v),
|
|
112
|
+
paddingRight: (n, v) => n.setPadding(Yoga.EDGE_RIGHT, v),
|
|
113
|
+
paddingBottom: (n, v) => n.setPadding(Yoga.EDGE_BOTTOM, v),
|
|
114
|
+
paddingLeft: (n, v) => n.setPadding(Yoga.EDGE_LEFT, v),
|
|
115
|
+
gap: (n, v) => n.setGap(Yoga.GUTTER_ALL, v ?? 0),
|
|
116
|
+
rowGap: (n, v) => n.setGap(Yoga.GUTTER_ROW, v ?? 0),
|
|
117
|
+
columnGap: (n, v) => n.setGap(Yoga.GUTTER_COLUMN, v ?? 0),
|
|
118
|
+
aspectRatio: (n, v) => n.setAspectRatio(v),
|
|
119
|
+
display: (n, v) =>
|
|
120
|
+
n.setDisplay(pick(DISPLAY, v, 'display') ?? Yoga.DISPLAY_FLEX),
|
|
121
|
+
overflow: (n, v) =>
|
|
122
|
+
n.setOverflow(pick(OVERFLOW, v, 'overflow') ?? Yoga.OVERFLOW_VISIBLE),
|
|
123
|
+
borderWidth: (n, v) => n.setBorder(Yoga.EDGE_ALL, v ?? 0),
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Props that only affect painting, not geometry.
|
|
127
|
+
const PAINT_PROPS = new Set([
|
|
128
|
+
'backgroundColor',
|
|
129
|
+
'borderColor',
|
|
130
|
+
'borderRadius',
|
|
131
|
+
'zIndex',
|
|
132
|
+
]);
|
|
133
|
+
|
|
134
|
+
// Text style props. All affect measurement except color.
|
|
135
|
+
export const TEXT_LAYOUT_PROPS = new Set([
|
|
136
|
+
'fontFamily',
|
|
137
|
+
'fontSize',
|
|
138
|
+
'fontWeight',
|
|
139
|
+
'fontStyle',
|
|
140
|
+
'textAlign',
|
|
141
|
+
'lineHeight',
|
|
142
|
+
]);
|
|
143
|
+
|
|
144
|
+
export const isLayoutProp = (name) =>
|
|
145
|
+
Object.prototype.hasOwnProperty.call(LAYOUT_APPLIERS, name);
|
|
146
|
+
export const isPaintProp = (name) => PAINT_PROPS.has(name);
|
|
147
|
+
export const isEventProp = (name) => /^on[A-Z]/.test(name);
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Apply changed layout props to a yoga node.
|
|
151
|
+
* @returns true if any layout-affecting prop changed
|
|
152
|
+
*/
|
|
153
|
+
export function applyLayoutStyle(yogaNode, props, oldProps = {}) {
|
|
154
|
+
let changed = false;
|
|
155
|
+
for (const key of Object.keys(LAYOUT_APPLIERS)) {
|
|
156
|
+
if (props[key] !== oldProps[key]) {
|
|
157
|
+
LAYOUT_APPLIERS[key](yogaNode, props[key]);
|
|
158
|
+
changed = true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return changed;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** @returns true if any paint-only prop changed */
|
|
165
|
+
export function paintPropsChanged(props, oldProps = {}) {
|
|
166
|
+
for (const key of PAINT_PROPS) {
|
|
167
|
+
if (props[key] !== oldProps[key]) return true;
|
|
168
|
+
}
|
|
169
|
+
return props.color !== oldProps.color;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** Resolved text style (TextLayout base style) from props + inherited. */
|
|
173
|
+
export function textStyleFrom(props, inherited) {
|
|
174
|
+
return {
|
|
175
|
+
family: props.fontFamily ?? inherited.family,
|
|
176
|
+
size: props.fontSize ?? inherited.size,
|
|
177
|
+
weight: props.fontWeight ?? inherited.weight,
|
|
178
|
+
style: props.fontStyle ?? inherited.style,
|
|
179
|
+
color: props.color ?? inherited.color,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export const DEFAULT_TEXT_STYLE = {
|
|
184
|
+
family: 'sans-serif',
|
|
185
|
+
size: 14,
|
|
186
|
+
weight: 'normal',
|
|
187
|
+
style: 'normal',
|
|
188
|
+
color: 'black',
|
|
189
|
+
};
|
package/.npmignore
DELETED
package/combobox.jsx
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
var React = require('./react-x11');
|
|
2
|
-
var View = React.View;
|
|
3
|
-
var Text = React.Text;
|
|
4
|
-
var P = React.P;
|
|
5
|
-
|
|
6
|
-
module.exports = function() {
|
|
7
|
-
|
|
8
|
-
this.render = function() {
|
|
9
|
-
function handleClick(pt) {
|
|
10
|
-
console.log('handle click!', pt);
|
|
11
|
-
this.setProps({
|
|
12
|
-
style: {
|
|
13
|
-
color: parseInt(0.1*(pt.x - this.props.left)*(pt.y - this.props.top))
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
console.log(this.props.style);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
var p = <P onClick={ handleClick }>
|
|
20
|
-
Lorem ipsum foo bar blah blah
|
|
21
|
-
Lorem ipsum foo bar blah blah
|
|
22
|
-
Lorem ipsum foo bar blah blah
|
|
23
|
-
Lorem ipsum foo bar blah blah
|
|
24
|
-
Lorem ipsum foo bar blah blah
|
|
25
|
-
Lorem ipsum foo bar blah blah
|
|
26
|
-
Lorem ipsum foo bar blah blah
|
|
27
|
-
Lorem ipsum foo bar blah blah
|
|
28
|
-
Lorem ipsum foo bar blah blah
|
|
29
|
-
Lorem ipsum foo bar blah blah
|
|
30
|
-
Lorem ipsum foo bar blah blah
|
|
31
|
-
Lorem ipsum foo bar blah blah
|
|
32
|
-
Lorem ipsum foo bar blah blah
|
|
33
|
-
Lorem ipsum foo bar blah blah
|
|
34
|
-
Lorem ipsum foo bar blah blah
|
|
35
|
-
Lorem ipsum foo bar blah blah
|
|
36
|
-
</P>
|
|
37
|
-
|
|
38
|
-
var haha = 1;
|
|
39
|
-
|
|
40
|
-
var pp = <View style={ { color: 0xffffff } }>
|
|
41
|
-
<View style={{ color: 0xffff00 }} >A lot of flexboxes with flexWrap=wrap </View>
|
|
42
|
-
<View style={{ color: 0xf0ff0f }}>{ p }</View>
|
|
43
|
-
</View>
|
|
44
|
-
|
|
45
|
-
var content = <View style={ { flexDirection: 'column', color: 0xfefefe, justifyContent: 'space-between', alignItems: 'stretch' } }>
|
|
46
|
-
<View test="foo" onMousemove={ function(ev) { console.log(ev.x, ev.y); } }>
|
|
47
|
-
<Text text={ "haha " + haha }/>
|
|
48
|
-
</View>
|
|
49
|
-
<View foo="test" style={ { color: 0xffa0a0 } } onClick={ function() { console.log(this.props.foo); } }>
|
|
50
|
-
Subview 0.1
|
|
51
|
-
</View>
|
|
52
|
-
<View foo="test" style={ { color: 0xa0a0a0, padding: 20, alignItems: 'stretch' } }>
|
|
53
|
-
{ p }
|
|
54
|
-
<View foo="test" style={ { color: 0xffffff, padding: 25 } } onMousemove={ handleClick }>
|
|
55
|
-
Subview 0.2.1
|
|
56
|
-
</View>
|
|
57
|
-
</View>
|
|
58
|
-
</View>
|
|
59
|
-
|
|
60
|
-
//setInterval( function() {
|
|
61
|
-
// console.log('set haha to ' + haha);
|
|
62
|
-
// haha++;
|
|
63
|
-
// content.props.children[0].props.children[0].props.text = ''+ haha;
|
|
64
|
-
//}, 1000);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return content;
|
|
68
|
-
}
|
|
69
|
-
}
|
package/react-x11.js
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
//var x11 = require('x11');
|
|
2
|
-
//var React = {}
|
|
3
|
-
//React.createConnection = function(cb) {
|
|
4
|
-
// x11.createConnection();
|
|
5
|
-
//};
|
|
6
|
-
|
|
7
|
-
var clone = function(obj) {
|
|
8
|
-
return JSON.parse(JSON.stringify(obj));
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
module.exports = {
|
|
12
|
-
createElement: function() {
|
|
13
|
-
//return arguments;
|
|
14
|
-
|
|
15
|
-
var component = arguments[0];
|
|
16
|
-
var props = arguments[1];
|
|
17
|
-
var children = [];
|
|
18
|
-
var ch;
|
|
19
|
-
for (var i=2; i < arguments.length; ++i) {
|
|
20
|
-
ch = arguments[i];
|
|
21
|
-
if (typeof ch == 'string') {
|
|
22
|
-
children.push(new module.exports.Text({ text: ch }));
|
|
23
|
-
}
|
|
24
|
-
else
|
|
25
|
-
children.push(arguments[i]);
|
|
26
|
-
}
|
|
27
|
-
var c = new component(props, children);
|
|
28
|
-
c.hitTest = function(pt) {
|
|
29
|
-
var res = [];
|
|
30
|
-
if (c.props && c.props.left <= pt.x && c.props.top <= pt.y && c.props.left + c.props.width >= pt.x && c.props.top + c.props.height >= pt.y ) {
|
|
31
|
-
res.push(this);
|
|
32
|
-
if (this.props && this.props.children) {
|
|
33
|
-
for (var i=0; i < this.props.children.length; ++i) {
|
|
34
|
-
var ch = this.props.children[i];
|
|
35
|
-
if (ch && ch.hitTest) {
|
|
36
|
-
var hits = ch.hitTest(pt);
|
|
37
|
-
res = res.concat(hits);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return res;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
c.setProps = function(newProps) {
|
|
47
|
-
var e = c;
|
|
48
|
-
var needsUpdate = false;
|
|
49
|
-
for (var key in newProps) {
|
|
50
|
-
if (this.props[key] != newProps[key]) {
|
|
51
|
-
this.props[key] = newProps[key];
|
|
52
|
-
needsUpdate = true;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
this._needsUpdate = needsUpdate;
|
|
56
|
-
};
|
|
57
|
-
return c;
|
|
58
|
-
},
|
|
59
|
-
View: function(args, children) {
|
|
60
|
-
if (!args)
|
|
61
|
-
args = {};
|
|
62
|
-
this.props = args;
|
|
63
|
-
this.props.children = children;
|
|
64
|
-
this.props.style = args.style || { color: 0xa0a0a0 };
|
|
65
|
-
this.render = function() {
|
|
66
|
-
return this;
|
|
67
|
-
};
|
|
68
|
-
this.draw = function(ctx) {
|
|
69
|
-
console.log(this.props.style.color);
|
|
70
|
-
//ctx.setForeground(this.props.style.color);
|
|
71
|
-
ctx.fillRect(this.props.left, this.props.top, this.props.width, this.props.height, 0.5, 0.5, 0.5, 1);
|
|
72
|
-
//ctx.setForeground(0);
|
|
73
|
-
//ctx.rectangle(this.props);
|
|
74
|
-
if (this.props.children) {
|
|
75
|
-
this.props.children.forEach(function(c) {
|
|
76
|
-
c.draw(ctx);
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
},
|
|
81
|
-
Text: function Text(args) {
|
|
82
|
-
this.fontHeight = 12;
|
|
83
|
-
this.fontWidth = 5;
|
|
84
|
-
this.props = args;
|
|
85
|
-
//var width = ctx.measureText(this.props.text).width;
|
|
86
|
-
var width = this.props.text.length*15;
|
|
87
|
-
this.props.style = { margin: 5, width: width, height: 2*this.fontHeight };
|
|
88
|
-
if (!this.props.text)
|
|
89
|
-
this.props.text = '';
|
|
90
|
-
this.render = function() {
|
|
91
|
-
return this;
|
|
92
|
-
};
|
|
93
|
-
this.draw = function(ctx) {
|
|
94
|
-
//ctx.setForeground(0);
|
|
95
|
-
ctx.fillText(this.props.text, this.props.left, this.props.top + this.fontHeight);
|
|
96
|
-
};
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
P: function(args, children) {
|
|
100
|
-
this.props = args || {};
|
|
101
|
-
this.props.style = this.props.style || { flexDirection: 'row', flexWrap: 'wrap' };
|
|
102
|
-
this.props.p = children[0].props.text;
|
|
103
|
-
this.props.children = this.props.p.split(' ').map( function(w) { return new module.exports.createElement(module.exports.Text, { text: w, onMousemove: function() { console.log(this.props.text);} }); });
|
|
104
|
-
this.render = function() {
|
|
105
|
-
return this;
|
|
106
|
-
};
|
|
107
|
-
this.draw = function(ctx) {
|
|
108
|
-
//ctx.setForeground(0xfef0f0); //this.props.style.color);
|
|
109
|
-
console.log('P', this.props);
|
|
110
|
-
//ctx.fillRect(this.props);
|
|
111
|
-
//ctx.rectangle(this.props);
|
|
112
|
-
this.props.children.forEach(function(c) {
|
|
113
|
-
//ctx.setForeground(0);
|
|
114
|
-
//ctx.rectangle(c.props);
|
|
115
|
-
c.draw(ctx);
|
|
116
|
-
});
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
};
|
package/test-canvas.js
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
require('node-jsx').install();
|
|
2
|
-
|
|
3
|
-
var ntk = require('ntk');
|
|
4
|
-
|
|
5
|
-
ntk.createClient(main);
|
|
6
|
-
|
|
7
|
-
var computeLayout = require('css-layout');
|
|
8
|
-
var React = require('./react-x11');
|
|
9
|
-
var ComboBox = require('./combobox.jsx');
|
|
10
|
-
|
|
11
|
-
var clone = function(obj) {
|
|
12
|
-
return JSON.parse(JSON.stringify(obj));
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
function unprops(node) {
|
|
16
|
-
var props = clone(node.props);
|
|
17
|
-
delete props.children;
|
|
18
|
-
if (node.props.children)
|
|
19
|
-
props.children = node.props.children.map(unprops);
|
|
20
|
-
|
|
21
|
-
//console.log('UNPROPS:', props);
|
|
22
|
-
return props;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function reflow(node, width, height) {
|
|
26
|
-
var window = { style: { width: width, height: height, justifyContent: 'stretch', alignItems: 'stretch' }, children: [ unprops(node) ] };
|
|
27
|
-
window.children[0].style.width = width;
|
|
28
|
-
window.children[0].style.height = height;
|
|
29
|
-
var layout = computeLayout(window);
|
|
30
|
-
//console.log(layout);
|
|
31
|
-
function applyLayout(node, layout, left, top) {
|
|
32
|
-
|
|
33
|
-
//console.log(left, top, node);
|
|
34
|
-
//console.log(JSON.stringify(layout, null, 2));
|
|
35
|
-
//debugger
|
|
36
|
-
|
|
37
|
-
node.props.width = layout.width;
|
|
38
|
-
node.props.height = layout.height;
|
|
39
|
-
node.props.left = layout.left + left;
|
|
40
|
-
node.props.top = layout.top + top;
|
|
41
|
-
|
|
42
|
-
if (node.props.children)
|
|
43
|
-
for (var i=0; i < node.props.children.length; ++i) {
|
|
44
|
-
applyLayout(node.props.children[i], layout.children[i], layout.left + left, layout.top + top);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
applyLayout({ props: { children: [node] } }, layout, 0, 0);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function main(err, app) {
|
|
51
|
-
var pix = app.createPixmap({ depth: 24, width: 1000, height: 1000 });
|
|
52
|
-
var mainwnd = app.createWindow({title: "Layout demo", pixmap: pix}).map();
|
|
53
|
-
var rootEle = React.createElement(ComboBox, { foo: 'blah blah' });
|
|
54
|
-
|
|
55
|
-
var ctx = pix.getContext('2d');
|
|
56
|
-
var ctxWin = mainwnd.getContext('2d');
|
|
57
|
-
var black = ctx.createSolidPicture(0, 0, 0, 1);
|
|
58
|
-
ctx.setBackground(black);
|
|
59
|
-
ctx.font = '8mm CourierNew';
|
|
60
|
-
|
|
61
|
-
var rootNode;
|
|
62
|
-
var prevW = 0;
|
|
63
|
-
var prevH = 0;
|
|
64
|
-
mainwnd.on('resize', function(ev) {
|
|
65
|
-
if ( (ev.width != prevW) || (ev.height != prevH) ) {
|
|
66
|
-
console.log([prevW, ev.width, prevH, ev.height]);
|
|
67
|
-
rootNode = rootEle.render();
|
|
68
|
-
reflow(rootNode, ev.width, ev.height);
|
|
69
|
-
rootNode.draw(ctx);
|
|
70
|
-
// TODO
|
|
71
|
-
ctxWin.draw(ctx);
|
|
72
|
-
prevW = ev.width;
|
|
73
|
-
prevH = ev.height;
|
|
74
|
-
}
|
|
75
|
-
}).on('expose', function(ev) {
|
|
76
|
-
ctxWin.draw(ctx);
|
|
77
|
-
}).on('mousedown', function(ev) {
|
|
78
|
-
if (!rootNode) return;
|
|
79
|
-
// 1 build list of matching views
|
|
80
|
-
// 2 check for handlers up
|
|
81
|
-
var hits = rootNode.hitTest(ev);
|
|
82
|
-
for (var i=1; i <= hits.length; i++) {
|
|
83
|
-
var component = hits[hits.length - i];
|
|
84
|
-
if (component.props.onClick) {
|
|
85
|
-
component.props.onClick.call(component, ev);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}).on('mousemove', function(ev) {
|
|
89
|
-
if (!rootNode) return;
|
|
90
|
-
var hits = rootNode.hitTest(ev);
|
|
91
|
-
for (var i=1; i <= hits.length; i++) {
|
|
92
|
-
var component = hits[hits.length - i];
|
|
93
|
-
if (component.props.onMousemove) {
|
|
94
|
-
component.props.onMousemove.call(component, ev);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
}
|