Add image resizing and TextInput

This commit is contained in:
kusti8 2019-09-15 11:57:40 -04:00
parent 56a1dbded7
commit 87a6f60750
11 changed files with 217 additions and 72 deletions

72
package-lock.json generated
View file

@ -2212,7 +2212,7 @@
"arr-flatten": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
"integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=",
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
"dev": true
},
"arr-union": {
@ -2717,7 +2717,7 @@
},
"camelcase-keys": {
"version": "2.1.0",
"resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
"resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
"integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
"dev": true,
"requires": {
@ -3007,7 +3007,7 @@
},
"concat-stream": {
"version": "1.6.2",
"resolved": "http://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
"dev": true,
"requires": {
@ -3208,7 +3208,7 @@
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
@ -3405,7 +3405,7 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
}
@ -3922,7 +3922,7 @@
},
"fs-extra": {
"version": "0.30.0",
"resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
"integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
"dev": true,
"requires": {
@ -3944,7 +3944,7 @@
"fs-readdir-recursive": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
"integrity": "sha1-4y/AMKLM7kSmtTcTCNpUvgs5fSc=",
"integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==",
"dev": true
},
"fs.realpath": {
@ -4584,7 +4584,7 @@
},
"got": {
"version": "6.7.1",
"resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz",
"resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
"integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
"dev": true,
"requires": {
@ -4820,6 +4820,11 @@
"minimatch": "^3.0.4"
}
},
"image-size": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.4.tgz",
"integrity": "sha512-GqPgxs+VkOr12aWwjSkyRzf5atzObWpFtiRuDgxCl2I/SDpZOKZFRD3iIAeAN6/usmn8SeLWRt7a8JRYK0Whbw=="
},
"import-fresh": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
@ -4875,7 +4880,7 @@
"ini": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc="
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
"invariant": {
"version": "2.2.4",
@ -4926,7 +4931,7 @@
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"dev": true
},
"is-callable": {
@ -5180,6 +5185,17 @@
"requires": {
"node-fetch": "^1.0.1",
"whatwg-fetch": ">=0.10.0"
},
"dependencies": {
"node-fetch": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
"requires": {
"encoding": "^0.1.11",
"is-stream": "^1.0.1"
}
}
}
},
"isstream": {
@ -6656,7 +6672,7 @@
},
"jsonfile": {
"version": "2.4.0",
"resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
"integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
"dev": true,
"requires": {
@ -7237,7 +7253,7 @@
},
"load-json-file": {
"version": "1.1.0",
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"dev": true,
"requires": {
@ -7448,7 +7464,7 @@
},
"meow": {
"version": "3.7.0",
"resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
"resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
"integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
"dev": true,
"requires": {
@ -7466,7 +7482,7 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
}
@ -7534,7 +7550,7 @@
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
"brace-expansion": "^1.1.7"
}
@ -7698,13 +7714,9 @@
"integrity": "sha512-FXWH6mqjWgU8ewuahp4spec8LkroFZK2NicOv6bNwZC3kcwZUI8LeZdG80UzTSLLhK4T7MsgNwlYDVRlDdfTDg=="
},
"node-fetch": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
"integrity": "sha1-mA9vcthSEaU0fGsrwYxbhMPrR+8=",
"requires": {
"encoding": "^0.1.11",
"is-stream": "^1.0.1"
}
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
},
"node-int64": {
"version": "0.4.0",
@ -7887,7 +7899,7 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
}
@ -8382,7 +8394,7 @@
},
"pretty-bytes": {
"version": "1.0.4",
"resolved": "http://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
"integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=",
"dev": true,
"requires": {
@ -8420,7 +8432,7 @@
"private": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
"integrity": "sha1-I4Hts2ifelPWUxkAYPz4ItLzaP8=",
"integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
"dev": true
},
"process-nextick-args": {
@ -8441,7 +8453,7 @@
"promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
"requires": {
"asap": "~2.0.3"
}
@ -8545,7 +8557,7 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
}
@ -9916,7 +9928,7 @@
},
"through2": {
"version": "0.2.3",
"resolved": "http://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
"resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
"integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
"dev": true,
"requires": {
@ -9932,7 +9944,7 @@
},
"readable-stream": {
"version": "1.1.14",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"dev": true,
"requires": {
@ -9944,7 +9956,7 @@
},
"string_decoder": {
"version": "0.10.31",
"resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
"dev": true
}

View file

@ -32,7 +32,9 @@
"color": "^3.1.2",
"fbjs": "^1.0.0",
"file-type": "^12.0.0",
"image-size": "^0.7.4",
"lodash": "^4.17.11",
"node-fetch": "^2.6.0",
"node-qt-napi": "github:kusti8/node-qt-napi",
"react": "^16.8.6",
"react-reconciler": "^0.20.4",

View file

@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
import propsUpdater from '../utils/propsUpdater';
import convertStyleSheet from '../utils/convertStyleSheet';
import { YogaComponent } from './YogaComponent';
import fetch from 'node-fetch';
export default p => {
const propTypes = {
@ -24,21 +25,47 @@ export default p => {
style: {},
onResponderGrant: () => {},
onResponderRelease: () => {},
resizeMode: 'stretch',
};
const element = new qt.QLabel();
element.setScaledContents(false);
const pixElement = new qt.QPixmap();
let props = { ...p };
props = propChecker(props, propTypes, defaultProps, 'Image');
let resizeMode = props.resizeMode;
const resizeMode = { r: props.resizeMode || 'stretch' };
const applyPixSize = (width, height, mode) => {};
const applyPixSize = (width, height, mode) => {
console.log('Set size', width, height);
console.log('Repeating', mode);
console.log(element.width(), element.height());
element.setAlignment(qt.Alignment.AlignLeft | qt.Alignment.AlignVCenter);
if (mode == 'cover') {
pixElement.scaled(
width,
height,
qt.AspectRatioMode.KeepAspectRatioByExpanding
);
} else if (mode == 'contain') {
pixElement.scaled(width, height, qt.AspectRatioMode.KeepAspectRatio);
} else if (mode == 'stretch') {
console.log('Scaled', width, height);
pixElement.scaled(width, height, qt.AspectRatioMode.IgnoreAspectRatio);
} else if (mode == 'center') {
element.setAlignment(qt.Alignment.AlignCenter);
pixElement.scaled(width, height, qt.AspectRatioMode.KeepAspectRatio);
} else if (mode == 'repeat') {
pixElement.scaledTile(width, height);
}
element.setPixmap(pixElement);
element.show();
element.adjustSize();
console.log('Pix size', pixElement.width(), pixElement.height());
};
const yogaProps = YogaComponent(element, layout => {
applyPixSize(layout.width, layout.height, resizeMode);
applyPixSize(layout.width, layout.height, resizeMode.r);
});
const handlers = {
@ -79,11 +106,39 @@ export default p => {
[handlers, 'onResponderGrant', 'onResponderRelease'],
{
style: style => {
if (style.resizeMode) {
console.log(style);
resizeMode.r = style.resizeMode;
}
element.setStyleSheet(convertStyleSheet(style));
yogaProps.applyYogaStyle(style);
},
resizeMode: r => {
resizeMode = r;
resizeMode.r = r;
},
source: source => {
if (source.uri) {
// need to figure out what width and height work with, and also work with arrays
if (
source.uri.startsWith('http://') ||
source.uri.startsWith('https://') ||
source.uri.startsWith('ftp://')
) {
fetch(source.uri, {
method: source.method || 'GET',
body: source.body,
headers: source.headers,
})
.then(out => out.buffer())
.then(out => {
pixElement.loadFromData(out);
element.setPixmap(pixElement);
});
} else {
pixElement.load(source.uri);
element.setPixmap(pixElement);
}
}
},
}
);

View file

@ -25,6 +25,7 @@ export default props => {
const queue = [host];
while (queue.length) {
const next = queue.pop();
console.log(next.element);
if (next && next.applyYoga) {
let root = true;
if (next.parent && next.parent.applyYoga) {
@ -45,6 +46,7 @@ export default props => {
};
const afterCommit = host => {
console.log('After commit');
traverseYoga(host);
};

View file

@ -0,0 +1,76 @@
import propChecker from '../utils/propChecker';
import { disconnectDevtools } from '../devtools';
import qt from 'node-qt-napi';
import { Container } from './Container';
import PropTypes from 'prop-types';
import propsUpdater from '../utils/propsUpdater';
import convertStyleSheet from '../utils/convertStyleSheet';
import { YogaComponent } from './YogaComponent';
export default p => {
const propTypes = {
style: PropTypes.object,
onChangeText: PropTypes.func,
value: PropTypes.string,
};
const defaultProps = {
style: {},
onChangeText: () => {},
value: '',
};
const element = new qt.QLineEdit();
let props = { ...p };
props = propChecker(props, propTypes, defaultProps, 'TextInput');
const yogaProps = YogaComponent(element);
const handlers = {
onChangeText: props.onChangeText,
};
element.textChangedEvent(text => {
handlers.onChangeText(text);
});
const containerProps = Container(
child => {
child.element.setParent(element);
if (child.node) {
yogaProps.node.insertChild(child.node, yogaProps.node.getChildCount());
}
},
child => {
child.element.del();
if (child.node) {
yogaProps.node.removeChild(child.node);
}
},
(child, i) => {
child.element.setParent(element);
if (child.node) {
yogaProps.node.insertChild(child.node, i);
}
}
);
const updateProps = propsUpdater([handlers, 'onChangeText'], {
style: style => {
element.setStyleSheet(convertStyleSheet(style));
yogaProps.applyYogaStyle(style);
},
value: value => {
element.setText(value);
},
});
updateProps(props);
return {
...containerProps,
...yogaProps,
element,
updateProps,
};
};

View file

@ -47,11 +47,12 @@ export default p => {
style: style => {
element.setStyleSheet(convertStyleSheet(style));
const size = percentToSize(style.width, style.height);
if (size.h) {
element.resize(element.width(), size.h);
}
if (size.w) {
if (size.h && size.w) {
element.resize(size.w, size.h);
} else if (size.w) {
element.resize(size.w, element.height());
} else if (size.h) {
element.resize(element.width(), size.h);
}
},
});

View file

@ -4,5 +4,7 @@ import Window from './Window';
import View from './View';
import VirtualText from './VirtualText';
import RootText from './RootText';
import Image from './Image';
import TextInput from './TextInput';
export { App, Root, Window, View, VirtualText, RootText };
export { App, Root, Window, View, VirtualText, RootText, Image, TextInput };

View file

@ -16,6 +16,8 @@ const View = 'VIEW';
const App = 'APP';
const VirtualText = 'VIRTUALTEXT';
const RootText = 'ROOTTEXT';
const Image = 'IMAGE';
const TextInput = 'TEXTINPUT';
export {
AppRegistry,
@ -30,4 +32,6 @@ export {
TouchableOpacity,
TouchableHighlight,
Button,
Image,
TextInput,
};

View file

@ -1,4 +1,13 @@
import { Root, App, View, Window, VirtualText, RootText } from '../components/';
import {
Root,
App,
View,
Window,
VirtualText,
RootText,
Image,
TextInput,
} from '../components/';
// Creates an element with an element type, props and a root instance
function createElement(type, props) {
@ -9,6 +18,8 @@ function createElement(type, props) {
WINDOW: () => new Window(props),
VIRTUALTEXT: () => new VirtualText(props),
ROOTTEXT: () => new RootText(props),
IMAGE: () => new Image(props),
TEXTINPUT: () => new TextInput(props),
default: undefined,
};
return COMPONENTS[type]() || COMPONENTS.default;

View file

@ -2,6 +2,7 @@ import Module from 'module';
import fileType from 'file-type';
import readChunk from 'read-chunk';
import fs from 'fs';
import sizeOf from 'image-size';
const originalLoader = Module._load;
@ -11,5 +12,6 @@ Module._load = function(request, parent) {
if (type.split('/')[0] != 'image')
return originalLoader.apply(this, arguments);
return fs.readFileSync(request);
const size = sizeOf(request);
return { uri: request, width: size.width, height: size.height };
};

View file

@ -10,6 +10,8 @@ import {
TouchableOpacity,
TouchableHighlight,
Button,
Image,
TextInput,
} from './src/';
class Example extends Component {
@ -18,42 +20,18 @@ class Example extends Component {
a: true,
};
componentDidMount() {
setTimeout(() => this.setState({ test: 'dsawewwww' }), 3000);
setTimeout(() => this.setState({ a: false }), 3000);
//setTimeout(() => this.setState({ test: "dsawewwww" }), 3000);
//setTimeout(() => this.setState({ a: false }), 3000);
}
render() {
return (
<App>
<Window style={{ height: '50%', width: '10%' }}>
<View
style={{ backgroundColor: 'red', flex: 1, margin: 30, padding: 30 }}
>
<View
style={{
backgroundColor: 'black',
flex: 1,
justifyContent: 'space-between',
}}
>
<Button onPress={() => console.log('Pressed')} title="Hello" />
<View style={{ backgroundColor: 'yellow', height: 10 }} />
<View style={{ backgroundColor: 'purple', height: 10 }} />
</View>
{this.state.a && (
<View style={{ backgroundColor: 'green', flex: 1 }} />
)}
<View style={{ backgroundColor: 'blue', flex: 1 }} />
<Text style={{ fontSize: 20 }}>
{this.state.test}
{this.state.a && <Text style={{ color: 'white' }}>Hello2</Text>}
</Text>
</View>
<Image
style={{ height: '100%', width: '100%', resizeMode: 'repeat' }}
source={require('/home/kusti8/Pictures/test_small.jpg')}
/>
</Window>
{this.state.a && (
<Window>
<View style={{ backgroundColor: 'blue' }} />
</Window>
)}
</App>
);
}