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

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 };
};