diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 5122821..6e3ea23 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -1,27 +1,29 @@ -- [Home](/) -- [Quick start](quickstart.md) -- [Packaging](packaging.md) -- [Universal Props](component_APIs/universal_props.md) -- Components - - [Box](component_APIs/box.md) - - [Button](component_APIs/button.md) - - [Checkbox](component_APIs/checkbox.md) - - [ColorButton](component_APIs/color_button.md) - - [Form](component_APIs/form.md) - - [Grid](component_APIs/grid.md) - - [Grid Children](component_APIs/grid_components.md) - - [Group](component_APIs/group.md) - - [Menu](component_APIs/menu.md) - - [Menu.Item](component_APIs/menu_item.md) - - [Picker](component_APIs/picker.md) - - [ProgressBar](component_APIs/progress_bar.md) - - [RadioButtons](component_APIs/radio_buttons.md) - - [Separator](component_APIs/separator.md) - - [Slider](component_APIs/slider.md) - - [Spinbox](component_APIs/spinbox.md) - - [Tab](component_APIs/tab.md) - - [TextInput](component_APIs/textinput.md) - - [Window](component_APIs/window.md) +* [Home](/) +* [Quick start](quickstart.md) +* [Packaging](packaging.md) +* [Universal Props](component_APIs/universal_props.md) +* Components -- Methods - - [Dialog](methods/dialog.md) \ No newline at end of file + * [App](component_APIs/app.md) + * [Box](component_APIs/box.md) + * [Button](component_APIs/button.md) + * [Checkbox](component_APIs/checkbox.md) + * [ColorButton](component_APIs/color_button.md) + * [Form](component_APIs/form.md) + * [Grid](component_APIs/grid.md) + * [Grid Children](component_APIs/grid_components.md) + * [Group](component_APIs/group.md) + * [Menu](component_APIs/menu.md) + * [Menu.Item](component_APIs/menu_item.md) + * [Picker](component_APIs/picker.md) + * [ProgressBar](component_APIs/progress_bar.md) + * [RadioButtons](component_APIs/radio_buttons.md) + * [Separator](component_APIs/separator.md) + * [Slider](component_APIs/slider.md) + * [Spinbox](component_APIs/spinbox.md) + * [Tab](component_APIs/tab.md) + * [TextInput](component_APIs/textinput.md) + * [Window](component_APIs/window.md) + +* Methods + * [Dialog](methods/dialog.md) diff --git a/docs/component_APIs/app.md b/docs/component_APIs/app.md new file mode 100644 index 0000000..5fbb281 --- /dev/null +++ b/docs/component_APIs/app.md @@ -0,0 +1,35 @@ +# App + +The app is the container for the entire program and holds Windows and Menus. + +```jsx +import React, { Component } from 'react'; + +import { render, Window, App } from 'proton-native'; + +class Example extends Component { + render() { + return ( + + + + ); + } +} + +render(); +``` + +## Props + +* [onShouldQuit](#onShouldQuit) + +## Reference + +### onShouldQuit + +Called when the quit menu item is called, right before the entire app quits. + +| **Type** | **Required** | **Default** | +| ---------- | ------------ | ----------- | +| function() | No | () => {} | diff --git a/docs/component_APIs/window.md b/docs/component_APIs/window.md index ccffc64..8cb59ad 100644 --- a/docs/component_APIs/window.md +++ b/docs/component_APIs/window.md @@ -13,7 +13,7 @@ class Example extends Component { render() { return ( - + ); } @@ -24,18 +24,17 @@ render(); ## Props -- [title](#title) -- [size](#size) -- [menuBar](#menuBar) -- [margined](#margined) -- [position](#position) -- [fullscreen](#fullscreen) -- [borderless](#borderless) -- [lastWindow](#lastWindow) -- [closed](#closed) -- [onClose](#onClose) -- [onPositionChange](#onPositionChange) -- [onContentSizeChange](#onContentSizeChange) +* [title](#title) +* [size](#size) +* [menuBar](#menuBar) +* [margined](#margined) +* [fullscreen](#fullscreen) +* [borderless](#borderless) +* [lastWindow](#lastWindow) +* [closed](#closed) +* [onClose](#onClose) +* [onPositionChange](#onPositionChange) +* [onContentSizeChange](#onContentSizeChange) ## Reference @@ -44,93 +43,77 @@ render(); The title of the window. Will be shown at the top left ribbon. | **Type** | **Required** | **Default** | -| --- | --- | --- | -| string | No | '' | +| -------- | ------------ | ----------- | +| string | No | '' | ### size How big the window is when the application is first started. -| **Type** | **Required** | **Default** | -| --- | --- | --- | -| object {h: number, w: number} | No | {h: 500, w: 500} | +| **Type** | **Required** | **Default** | +| ----------------------------- | ------------ | ---------------- | +| object {h: number, w: number} | No | {h: 500, w: 500} | ### menuBar Whether a menubar will be shown on the top of the window. | **Type** | **Required** | **Default** | -| --- | --- | --- | -| bool | No | true | +| -------- | ------------ | ----------- | +| bool | No | true | ### margined Whether all children will have a margin around them and the outer edge of the window. | **Type** | **Required** | **Default** | -| --- | --- | --- | -| bool | No | false | - -### position - -The location where the window will be started, where (0,0) is top left. - -| **Type** | **Required** | **Default** | -| --- | --- | --- | -| object {x: number, y: number} | No | {x: 300, y: 300} | +| -------- | ------------ | ----------- | +| bool | No | false | ### fullscreen Whether the window will be fullscreen on start. | **Type** | **Required** | **Default** | -| --- | --- | --- | -| bool | No | false | +| -------- | ------------ | ----------- | +| bool | No | false | ### borderless Whether the window will have a border on the inside. | **Type** | **Required** | **Default** | -| --- | --- | --- | -| bool | No | false | +| -------- | ------------ | ----------- | +| bool | No | false | ### lastWindow Whether the window is the last window. If set to `true`, then the program will quit once the window is closed. | **Type** | **Required** | **Default** | -| --- | --- | --- | -| bool | No | true | +| -------- | ------------ | ----------- | +| bool | No | true | ### closed Whether the window is closed. If set to closed, then the window will be closed. | **Type** | **Required** | **Default** | -| --- | --- | --- | -| bool | No | false | +| -------- | ------------ | ----------- | +| bool | No | false | ### onClose Called when the window is closed. -| **Type** | **Required** | -| --- | --- | -| function() | No | - -### onPositionChange - -Called when the window position is changed. The new position is passed as an argument, in an object. - -| **Type** | **Required** | -| --- | --- | -| function({x: number, y: number}) | No | +| **Type** | **Required** | +| ---------- | ------------ | +| function() | No | ### onContentSizeChange Called when the window size is changed by the user. The new size is passed as an argument, in an object. -| **Type** | **Required** | -| --- | --- | -| function({h: number, y: number}) | No | \ No newline at end of file +| **Type** | **Required** | +| -------------------------------- | ------------ | +| function({h: number, y: number}) | No | diff --git a/examples/Notepad/index.js b/examples/Notepad/index.js index d1523ca..bdb20ad 100644 --- a/examples/Notepad/index.js +++ b/examples/Notepad/index.js @@ -1,46 +1,66 @@ import React, { Component } from 'react'; -import fs from 'fs' -import { render, Window, App, TextInput, Dialog, Menu, Box } from 'proton-native'; +import fs from 'fs'; +import { + render, + Window, + App, + TextInput, + Dialog, + Menu, + Box, +} from 'proton-native'; class Notepad extends Component { - state = {text: ''} + state = { text: '' }; - save() { - const filename = Dialog('Save') - fs.writeFile(filename, this.state.text) - } + save() { + const filename = Dialog('Save'); + fs.writeFileSync(filename, this.state.text); + } - open() { - const filename = Dialog('Open') - fs.readFile(filename, (err, data) => { - if (err) - throw err - this.setState({text: data}) - }) + open() { + const filename = Dialog('Open'); + if (filename) { + let data = fs.readFileSync(filename); + this.setState({ text: data }); } + } - shouldComponentUpdate(nextProps, nextState) { - if(typeof nextState.text === 'string') - return false // nextState is set from input - else - return true // nextState is set from file - } + shouldComponentUpdate(nextProps, nextState) { + if (typeof nextState.text === 'string') + return false; // nextState is set from input + else return true; // nextState is set from file + } - render() { - return ( - - - this.open()}>Open - this.save()}>Save - - - - this.setState({text})} multiline={true}>{this.state.text} - - - - ); - } + render() { + return ( + console.log('Quitting')}> + + this.open()}> + Open + + this.save()}> + Save + + + + console.log('Closing')} + title="Notes" + size={{ w: 500, h: 500 }} + > + + this.setState({ text })} + multiline={true} + > + {this.state.text} + + + + + ); + } } render(); diff --git a/package-lock.json b/package-lock.json index 3b27eee..56b5099 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1643,6 +1643,11 @@ "readdirp": "2.1.0" } }, + "chownr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" + }, "ci-info": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz", @@ -2193,10 +2198,10 @@ "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=" }, "emscripten-library-decorator": { - "version": "0.1.8", + "version": "0.2.2", "resolved": - "https://registry.npmjs.org/emscripten-library-decorator/-/emscripten-library-decorator-0.1.8.tgz", - "integrity": "sha1-Z4Zo/58hCvlxuPXHgPsO9vzDrls=" + "https://registry.npmjs.org/emscripten-library-decorator/-/emscripten-library-decorator-0.2.2.tgz", + "integrity": "sha1-0DXwI+KoTGgwXMhCze6jjmdoPEA=" }, "encoding": { "version": "0.1.12", @@ -2545,6 +2550,16 @@ "rimraf": "2.4.5" } }, + "fs-minipass": { + "version": "1.2.5", + "resolved": + "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", + "integrity": + "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "requires": { + "minipass": "2.2.1" + } + }, "fs-readdir-recursive": { "version": "1.1.0", "resolved": @@ -4805,10 +4820,11 @@ } }, "libui-download": { - "version": "0.1.0", + "version": "1.0.0", "resolved": - "https://registry.npmjs.org/libui-download/-/libui-download-0.1.0.tgz", - "integrity": "sha1-/LF2cjJCQ5cpCxxWNR5obPOwjZ0=", + "https://registry.npmjs.org/libui-download/-/libui-download-1.0.0.tgz", + "integrity": + "sha512-nW3PgUCPQoxKBce9gkLkmiUH2163FpwFLnXorO/IJhFC4h7JgJRPRKWSGYZvlrhU18rZr93DqECE90cCS2pW1Q==", "requires": { "debug": "2.6.9", "home-path": "1.0.5", @@ -4819,7 +4835,7 @@ "rc": "1.2.5", "regenerator-runtime": "0.9.6", "request": "2.83.0", - "tar.gz": "1.0.7" + "tar": "4.4.0" }, "dependencies": { "regenerator-runtime": { @@ -4831,12 +4847,15 @@ } }, "libui-node": { - "version": - "github:kusti8/libui-node#d0dd94a2c2a67c597902b51f0640500f06038bea", + "version": "0.1.0", + "resolved": + "https://registry.npmjs.org/libui-node/-/libui-node-0.1.0.tgz", + "integrity": + "sha512-wTULYnkI+k2C1+kX1rbTUh2d9JvK97/XtZxa8c9BnskueYNX6L5+kR0eyfT39ro8ULYkYW8vF3T6FWxGthbqiA==", "requires": { "autogypi": "0.2.2", - "libui-download": "0.1.0", - "nbind": "0.2.1", + "libui-download": "1.0.0", + "nbind": "0.3.15", "node-gyp": "3.6.2" } }, @@ -5548,6 +5567,31 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, + "minipass": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.1.tgz", + "integrity": + "sha512-u1aUllxPJUI07cOqzR7reGmQxmCqlH88uIIsf6XZFEWgw7gXKpJdR+5R9Y3KEDmWYkdIz9wXZs3C0jOPxejk/Q==", + "requires": { + "yallist": "3.0.2" + }, + "dependencies": { + "yallist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", + "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=" + } + } + }, + "minizlib": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", + "integrity": + "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", + "requires": { + "minipass": "2.2.1" + } + }, "mixin-deep": { "version": "1.3.1", "resolved": @@ -5579,11 +5623,6 @@ "minimist": "0.0.8" } }, - "mout": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.1.tgz", - "integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k=" - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -5602,7 +5641,8 @@ "nan": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", - "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=" + "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", + "optional": true }, "nanomatch": { "version": "1.2.9", @@ -5651,13 +5691,22 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, "nbind": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/nbind/-/nbind-0.2.1.tgz", - "integrity": "sha1-94MIYSoY5460lyVsXJpxT2JlJW0=", + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/nbind/-/nbind-0.3.15.tgz", + "integrity": + "sha512-TrKLNRj5D8wZRJb7XmUNbA1W3iTigAEpm3qaGig5bEWY/iCT2IQBgBc2EUGO59FbRIGhx5hB/McVwqxlSGScVw==", "requires": { - "emscripten-library-decorator": "0.1.8", + "emscripten-library-decorator": "0.2.2", "mkdirp": "0.5.1", - "nan": "2.8.0" + "nan": "2.10.0" + }, + "dependencies": { + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": + "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" + } } }, "ncp": { @@ -5700,6 +5749,16 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } } } }, @@ -7330,33 +7389,23 @@ "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar.gz": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.7.tgz", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.0.tgz", "integrity": - "sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg==", + "sha512-gJlTiiErwo96K904FnoYWl+5+FBgS+FimU6GMh66XLdLa55al8+d4jeDfPoGwSNHdtWI5FJP6xurmVqhBuGJpQ==", "requires": { - "bluebird": "2.11.0", - "commander": "2.13.0", - "fstream": "1.0.11", - "mout": "0.11.1", - "tar": "2.2.1" + "chownr": "1.0.1", + "fs-minipass": "1.2.5", + "minipass": "2.2.1", + "minizlib": "1.1.0", + "mkdirp": "0.5.1", + "yallist": "3.0.2" }, "dependencies": { - "bluebird": { - "version": "2.11.0", - "resolved": - "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" + "yallist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", + "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=" } } }, diff --git a/package.json b/package.json index fdd12a8..c0a6428 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "color": "^3.0.0", "fbjs": "^0.8.16", "husky": "^0.14.3", - "libui-node": "kusti8/libui-node", + "libui-node": "^0.1.0", "lint-staged": "^7.0.0", "performance-now": "^2.1.0", "prop-types": "^15.6.0", diff --git a/src/components/App.js b/src/components/App.js index ee3a2f7..ec534c6 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,19 +1,35 @@ +import libui from 'libui-node'; import DesktopComponent, { universalPropTypes, universalDefaultProps, } from './DesktopComponent'; +import PropTypes from 'prop-types'; + class App extends DesktopComponent { constructor(root, props) { super(root, props); this.root = root; - this.props = props; + this.props = { ...props }; this.element = {}; + this.setDefaults(props); } render() { + libui.Ui.onShouldQuit(() => { + this.props.onShouldQuit(); + libui.stopLoop(); + }); this.renderChildNode(this); } } +App.PropTypes = { + onShouldQuit: PropTypes.func, +}; + +App.defaultProps = { + onShouldQuit: () => {}, +}; + export default App; diff --git a/src/components/DesktopComponent.js b/src/components/DesktopComponent.js index fa99423..3203db7 100644 --- a/src/components/DesktopComponent.js +++ b/src/components/DesktopComponent.js @@ -25,7 +25,6 @@ const functionMappings = { onToggle: 'onToggled', onSelect: 'onSelected', onContentSizeChange: 'onContentSizeChanged', - onPositionChange: 'onPositionChanged', }; class DesktopComponent { diff --git a/src/components/MenuBar.js b/src/components/MenuBar.js index 076d701..6e60262 100644 --- a/src/components/MenuBar.js +++ b/src/components/MenuBar.js @@ -71,7 +71,6 @@ MenuBar.Item.PropTypes = { MenuBar.Item.defaultProps = { children: '', - checked: false, type: ITEM, ...universalDefaultProps, }; diff --git a/src/components/Root.js b/src/components/Root.js index beb817d..3d824ae 100644 --- a/src/components/Root.js +++ b/src/components/Root.js @@ -3,14 +3,12 @@ import DesktopComponent, { universalPropTypes, universalDefaultProps, } from './DesktopComponent'; -import { start } from '../eventLoop'; // This creates the document instance class Root extends DesktopComponent { constructor() { super(); - libui.Ui.init(); - start(); + libui.startLoop(); } render() { this.renderChildNode(); diff --git a/src/components/Window.js b/src/components/Window.js index 365cf14..df47dff 100644 --- a/src/components/Window.js +++ b/src/components/Window.js @@ -4,7 +4,6 @@ import DesktopComponent, { } from './DesktopComponent'; import libui from 'libui-node'; import PropTypes from 'prop-types'; -import { stop } from '../eventLoop'; var CURRENT_WINDOW = null; @@ -34,21 +33,12 @@ class Window extends DesktopComponent { if (newProps.margined !== oldProps.margined) { this.element.margined = newProps.margined; } - if (newProps.position !== oldProps.position) { - this.element.position.x = newProps.position.x; - this.element.position.y = newProps.position.y; - } if (newProps.fullscreen !== oldProps.fullscreen) { this.element.fullscreen = newProps.fullscreen; } if (newProps.borderless !== oldProps.borderless) { this.element.borderless = newProps.borderless; } - // if (newProps.centered !== oldProps.centered) { - // if (newProps.centered) { - // this.element.center() - // } - // } if (newProps.closed !== oldProps.closed) { if (newProps.closed) { this.element.close(); @@ -69,12 +59,10 @@ class Window extends DesktopComponent { this.props.onClose(); this.element.close(); if (this.props.lastWindow) { - stop(); + libui.stopLoop(); } }); this.element.margined = this.props.margined; - this.element.position.x = this.props.position.x; - this.element.position.y = this.props.position.y; this.element.fullscreen = this.props.fullscreen; this.element.borderless = this.props.borderless; @@ -82,16 +70,10 @@ class Window extends DesktopComponent { this.element.center(); } - this.element.onPositionChanged(() => { - this.props.onPositionChange({ - x: this.element.position.x, - y: this.element.position.y, - }); - }); this.element.onContentSizeChanged(() => { this.props.onContentSizeChange({ - h: this.element.position.h, - w: this.element.position.w, + h: this.element.contentSize.h, + w: this.element.contentSize.w, }); }); CURRENT_WINDOW = this.element; @@ -109,17 +91,12 @@ Window.PropTypes = { }), menuBar: PropTypes.bool, margined: PropTypes.bool, - position: PropTypes.shape({ - x: PropTypes.number, - y: PropTypes.number, - }), fullscreen: PropTypes.bool, borderless: PropTypes.bool, //centered: PropTypes.bool, lastWindow: PropTypes.bool, closed: PropTypes.bool, onClose: PropTypes.func, - onPositionChange: PropTypes.func, onContentSizeChange: PropTypes.func, }; @@ -131,17 +108,12 @@ Window.defaultProps = { }, menuBar: true, margined: false, - position: { - x: 300, - y: 300, - }, fullscreen: false, borderless: false, //centered: true, lastWindow: true, closed: false, onClose: () => {}, - onPositionChange: () => {}, onContentSizeChange: () => {}, }; diff --git a/src/eventLoop.js b/src/eventLoop.js deleted file mode 100644 index 474d1ae..0000000 --- a/src/eventLoop.js +++ /dev/null @@ -1,26 +0,0 @@ -import libui from 'libui-node'; -import { setInterval, clearInterval } from 'timers'; - -var STARTED = false; -var timeout = null; - -export function start() { - if (STARTED) { - return; - } else { - STARTED = true; - } - libui.Ui.mainSteps(); - timeout = setInterval(() => libui.Ui.mainStep(1), 16); -} - -export function stop() { - if (!STARTED) { - return; - } else { - STARTED = false; - } - if (timeout) { - clearInterval(timeout); - } -}