diff --git a/docs/components.md b/docs/components.md index 45c0ef9..01f1c88 100644 --- a/docs/components.md +++ b/docs/components.md @@ -24,4 +24,4 @@ desktop. More detailed information can be seen [here](components/Window.md) | TouchableHighlight | activeOpacity, underlayColor, style, onPress, onLongPress | | TouchableOpacity | activeOpacity, style, onPress, onLongPress | | TouchableWithoutFeedback | onPress, onLongPress | -| View | style | +| View | style, onMouseMove, onMouseEnter, onMouseLeave | diff --git a/src/backends/qt.ts b/src/backends/qt.ts index 4a272e4..ba9b2da 100644 --- a/src/backends/qt.ts +++ b/src/backends/qt.ts @@ -12,12 +12,34 @@ export function desktopSize(): Size { export abstract class BaseElement { element: any; + hasMouseTracking() { + return this.element.hasMouseTracking(); + } + setMouseTracking(v: boolean) { + this.element.setMouseTracking(v); + } mousePressEvent(func: () => void) { this.element.mousePressEvent(func); } mouseReleaseEvent(func: () => void) { this.element.mouseReleaseEvent(func); } + mouseMoveEvent(func: (x: number, y: number) => void) { + // TODO: Mouse tracking should be turned of when the event handler + // is being removed (not changed to a new function) + // This probably needs teardown logic in propsUpdater function + if (!this.hasMouseTracking()) { + this.setMouseTracking(true); + } + + this.element.mouseMoveEvent(func); + } + enterEvent(func: () => void) { + this.element.enterEvent(func); + } + leaveEvent(func: () => void) { + this.element.leaveEvent(func); + } setStyleSheet(obj: object) { this.element.setStyleSheet(convertStyleSheet(obj)); } diff --git a/src/components/View.ts b/src/components/View.ts index 239bfcc..4dc39f5 100644 --- a/src/components/View.ts +++ b/src/components/View.ts @@ -6,6 +6,24 @@ import convertStyleSheet from "../utils/convertStyleSheet"; import { YogaComponent } from "./YogaComponent"; import { getBackend } from "../backends/index"; +interface Point { + x: number; + y: number; +} + +interface MouseMoveEvent { + point: Point; +} + +interface Props { + style: React.CSSProperties; + onResponderGrant: () => void; + onResponderRelease: () => void; + onMouseMove: (event: MouseMoveEvent) => void; + onMouseEnter: () => void; + onMouseLeave: () => void; +} + declare global { namespace JSX { interface IntrinsicElements { @@ -30,12 +48,18 @@ export default (p: Props) => { const propTypes = { style: PropTypes.object, onResponderGrant: PropTypes.func, - onResponderRelease: PropTypes.func + onResponderRelease: PropTypes.func, + onMouseMove: PropTypes.func, + onMouseEnter: PropTypes.func, + onMouseLeave: PropTypes.func }; const defaultProps = { style: {}, onResponderGrant: () => {}, - onResponderRelease: () => {} + onResponderRelease: () => {}, + onMouseMove: (event: MouseMoveEvent) => {}, + onMouseEnter: () => {}, + onMouseLeave: () => {} }; const ViewElement = getBackend()["ViewElement"]; @@ -48,7 +72,10 @@ export default (p: Props) => { const handlers = { onResponderGrant: props.onResponderGrant, - onResponderRelease: props.onResponderRelease + onResponderRelease: props.onResponderRelease, + onMouseMove: props.onMouseMove, + onMouseEnter: props.onMouseEnter, + onMouseLeave: props.onMouseLeave }; element.mousePressEvent(() => { @@ -63,6 +90,18 @@ export default (p: Props) => { } }); + element.mouseMoveEvent((x: number, y: number) => { + handlers.onMouseMove({ point: { x, y } }); + }); + + element.enterEvent(() => { + handlers.onMouseEnter(); + }); + + element.leaveEvent(() => { + handlers.onMouseLeave(); + }); + const containerProps = Container( child => { child.element.setParent(element); @@ -85,7 +124,13 @@ export default (p: Props) => { ); const updateProps = propsUpdater( - [handlers, "onResponderGrant", "onResponderRelease"], + [ + handlers, + "onResponderGrant", + "onResponderRelease", + "onMouseEnter", + "onMouseLeave" + ], { style: (style: React.CSSProperties) => { element.setStyleSheet(style); diff --git a/testprog.js b/testprog.js index 1876e48..806ad33 100644 --- a/testprog.js +++ b/testprog.js @@ -22,6 +22,9 @@ class Example extends Component { state = { test: 'dsdasdsa', a: true, + mouseState: 'idle', + x: 50, + y: 50, }; componentDidMount() { //setTimeout(() => this.setState({ test: "dsawewwww" }), 3000); @@ -35,6 +38,9 @@ class Example extends Component { style={{ height: '25%', width: '25%', backgroundColor: 'blue' }} > this.setState({ mouseState: 'MOUSE ENTERED' })} + onMouseLeave={() => this.setState({ mouseState: 'MOUSE LEFT' })} + onMouseMove={event => this.setState(event.point)} style={{ height: '50%', width: '100%', backgroundColor: 'green' }} >