diff --git a/README.md b/README.md index fdb2276c0..31529edce 100644 --- a/README.md +++ b/README.md @@ -43,16 +43,20 @@ Contributing developer docs link: https://github.com/master-atul/nodegui/tree/master/extras/devdocs - ## Building -yarn rebuild:addon [--qt_home_dir=/path/to/qt] +`yarn rebuild:addon [--qt_home_dir=/path/to/qt]` ### LICENSE +``` Since we do not in any way modify the code of Qt and only link to it dynamically, I beleive we are in compliance with the LGPL license requirements of QT. And hence this library can be licensed under its own License (for which we have chosen MIT License). The links to QT source code and appropriate license notices are attached. We try our best to abide by the software licenses and any non compliance is not by will. If there is some discrepancy please let us know in the issues and we will try and fix it up. If you follow the recommended build steps and do not statically link QT libraries on your own you are safe to use this library for commerical puropses (provided you abide by MIT License). +``` MIT +# TODO + +- Make https://github.com/nodegui/nodegui-quick-start diff --git a/demo.ts b/demo.ts index 98d4b9488..af7af1231 100644 --- a/demo.ts +++ b/demo.ts @@ -1,186 +1,29 @@ -import { QMainWindow } from "./src/lib/QtWidgets/QMainWindow"; -import { QWidget } from "./src/lib/QtGui/QWidget"; -import { QGridLayout } from "./src/lib/QtWidgets/QGridLayout"; -import { QLabel } from "./src/lib/QtWidgets/QLabel"; -import { - QPushButton, - QPushButtonEvents -} from "./src/lib/QtWidgets/QPushButton"; -import { QCheckBox } from "./src/lib/QtWidgets/QCheckBox"; -import { QProgressBar } from "./src/lib/QtWidgets/QProgressBar"; -import { QRadioButton } from "./src/lib/QtWidgets/QRadioButton"; -import { QLineEdit } from "./src/lib/QtWidgets/QLineEdit"; -import { FlexLayout } from "./src/lib/core/FlexLayout"; -import { QKeyEvent } from "./src/lib/QtGui/QEvent/QKeyEvent"; +import { QMainWindow, QWidget, QLabel, FlexLayout } from "./src/lib/index"; -// Test all widgets in this one. This works as of now! -const testGridLayout = () => { - const win = new QMainWindow(); - const view = new QWidget(); - win.setCentralWidget(view); +const win = new QMainWindow(); +//------------------------------- +const centralWidget = new QWidget(); +centralWidget.setObjectName("myroot"); +const rootLayout = new FlexLayout(); +centralWidget.setLayout(rootLayout); +//-------------------------------------- +const label = new QLabel(); +label.setObjectName("mylabel"); +label.setText("Hello World"); +//-------------------------------------- +rootLayout.addWidget(label); +win.setCentralWidget(centralWidget); +win.setStyleSheet( + ` + #myroot { + background-color: #009688; + } + #mylabel { + font-size: 16px; + font-weight: bold; + } + ` +); +win.show(); - const gridLayout = new QGridLayout(); - - const label = new QLabel(); - label.setText("Testing1234"); - label.setStyleSheet("background-color:blue; color:white;"); - - const button1 = new QPushButton(); - button1.addEventListener(QPushButtonEvents.clicked, isChecked => { - console.log("clicked", isChecked); - }); - button1.addEventListener(QPushButtonEvents.pressed, (...args) => { - console.log("pressed", ...args); - }); - button1.addEventListener(QPushButtonEvents.released, (...args) => { - console.log("released", ...args); - }); - button1.addEventListener(QPushButtonEvents.toggled, isToggled => { - console.log("toggled", isToggled); - }); - - button1.setText(`Button for Label with text: ${label.text()}`); - - const checkbox = new QCheckBox(); - checkbox.setText("Checkbox text"); - - const progressbar = new QProgressBar(); - - const radiobutton = new QRadioButton(); - - const lineedit = new QLineEdit(); - - gridLayout.addWidget(label); - gridLayout.addWidget(button1); - gridLayout.addWidget(checkbox); - gridLayout.addWidget(progressbar); - gridLayout.addWidget(radiobutton); - gridLayout.addWidget(lineedit); - - view.setLayout(gridLayout); - - win.show(); - return win; -}; - -// ----------------------------------------------- - -// BROKEN STUFF IN WINDOWS: -// FLEX DIRECTION ROW -// JUSTIFY CONTENT: SPACE-EVENLY, SPACE-AROUND -// ALIGNSELF: STRETCH - -const example1 = () => { - // rootView -> view1 -> label1 - // -> label2 - // -> view2 -> button - - const win = new QMainWindow(); - win.setStyleSheet(` - #root { - background-color: grey; - qproperty-qWidth: '100%'; - qproperty-qHeight: '100%'; - qproperty-alignItems: 'center'; - qproperty-justifyContent: 'center'; - qproperty-flex: 1; - } - #view1 { - background-color: green; - qproperty-flex: 1; - qproperty-alignItems: 'center'; - qproperty-justifyContent: 'center'; - qproperty-qWidth: '100%'; - } - #view2 { - background-color: orange; - qproperty-flex: 1; - qproperty-alignItems: 'center'; - qproperty-justifyContent: 'center'; - qproperty-qWidth: '100%'; - } - - `); - const rootView = new QWidget(); - rootView.setObjectName("root"); - const rootLayout = new FlexLayout(); - rootLayout.setFlexNode(rootView.getFlexNode()); - rootView.setLayout(rootLayout); - //----------------------- - const view1 = new QWidget(); - view1.setObjectName(`view1`); - const viewLayout = new FlexLayout(); - viewLayout.setFlexNode(view1.getFlexNode()); - view1.setLayout(viewLayout); - const label = new QLabel(); - label.setText("LABEL 1"); - label.setObjectName("label1"); - const label2 = new QLabel(); - label2.setObjectName("label2"); - label2.setText("LABEL 2"); - viewLayout.addWidget(label); - viewLayout.addWidget(label2); -//---------------------------- - const view2 = new QWidget(); - view2.setObjectName("view2"); - const view2Layout = new FlexLayout(); - view2Layout.setFlexNode(view2.getFlexNode()); - view2.setLayout(view2Layout); - const button = new QPushButton(); - button.setObjectName("button"); - button.setText("BUTTON"); - view2Layout.addWidget(button); -//----------------------------- - rootLayout.addWidget(view1); - rootLayout.addWidget(view2); - win.setCentralWidget(rootView); - win.show(); - return win; -}; - -const example2 = ()=>{ - const win = new QMainWindow(); - win.setStyleSheet(` - #root { - background-color: grey; - qproperty-qWidth: '100%'; - qproperty-qHeight: '100%'; - qproperty-alignItems: 'center'; - qproperty-justifyContent: 'center'; - qproperty-flexDirection: 'row'; - qproperty-flex: 1; - } - #view1 { - background-color: green; - qproperty-flex: 1; - qproperty-qHeight: '100%'; - } - #view2 { - background-color: orange; - qproperty-flex: 1; - qproperty-qHeight: '100%'; - } - - `); - const rootView = new QWidget(); - rootView.setObjectName("root"); - const rootLayout = new FlexLayout(); - rootLayout.setFlexNode(rootView.getFlexNode()); - rootView.setLayout(rootLayout); - //-------------------------------------- - const view1 = new QWidget(); - view1.setObjectName("view1"); - //-------------------------------------- - const view2 = new QWidget(); - view2.setObjectName("view2"); - //-------------------------------------- - rootLayout.addWidget(view1); - rootLayout.addWidget(view2); - win.setCentralWidget(rootView); - win.show(); - return win; -} - -// (global as any).win1 = testGridLayout(); //to keep gc from collecting -// (global as any).ex1 = example1(); //to keep gc from collecting -(global as any).ex2 = example2(); //to keep gc from collecting +(global as any).win = win; // To prevent win from being garbage collected. diff --git a/extras/devdocs/README.md b/extras/devdocs/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/extras/docs/README.md b/extras/docs/README.md new file mode 100644 index 000000000..a61e33f5f --- /dev/null +++ b/extras/docs/README.md @@ -0,0 +1,138 @@ +# Guides and Tutorials + +- [About NodeGui](tutorial/about.md) +- [Setting up the Development Environment](tutorial/development-environment.md) + - [Setting up macOS](tutorial/development-environment.md#setting-up-macos) + - [Setting up Windows](tutorial/development-environment.md#setting-up-windows) + - [Setting up Linux](tutorial/development-environment.md#setting-up-linux) + - [Choosing an Editor](tutorial/development-environment.md#a-good-editor) +- [Creating your First App](tutorial/first-app.md) + - [Hello World](tutorial/first-app.md#Hello-World) + - [NodeGui Development in a Nutshell](tutorial/first-app.md#NodeGui-development-in-a-nutshell) + - [Running Your App](tutorial/first-app.md#running-your-app) + +// BOOK MARK - TODO AFTER THIS + +- [Application Architecture](tutorial/application-architecture.md) + - [Main and Renderer Processes](tutorial/application-architecture.md#main-and-renderer-processes) + - [Using NodeGui's APIs](tutorial/application-architecture.md#using-NodeGui-apis) + - [Using Node.js APIs](tutorial/application-architecture.md#using-nodejs-apis) + - [Using Native Node.js Modules](tutorial/using-native-node-modules.md) +- Adding Features to Your App + - [Notifications](tutorial/notifications.md) + - [Recent Documents](tutorial/recent-documents.md) + - [Application Progress](tutorial/progress-bar.md) + - [Custom Dock Menu](tutorial/macos-dock.md) + - [Custom Windows Taskbar](tutorial/windows-taskbar.md) + - [Custom Linux Desktop Actions](tutorial/linux-desktop-actions.md) + - [Keyboard Shortcuts](tutorial/keyboard-shortcuts.md) + - [Offline/Online Detection](tutorial/online-offline-events.md) + - [Represented File for macOS BrowserWindows](tutorial/represented-file.md) + - [Native File Drag & Drop](tutorial/native-file-drag-drop.md) + - [Offscreen Rendering](tutorial/offscreen-rendering.md) + - [Supporting macOS Dark Mode](tutorial/mojave-dark-mode-guide.md) +- [Testing and Debugging](tutorial/application-debugging.md) + - [Debugging the Main Process](tutorial/debugging-main-process.md) + - [Debugging the Main Process with Visual Studio Code](tutorial/debugging-main-process-vscode.md) + - [Using Selenium and WebDriver](tutorial/using-selenium-and-webdriver.md) + - [Testing on Headless CI Systems (Travis, Jenkins)](tutorial/testing-on-headless-ci.md) + - [DevTools Extension](tutorial/devtools-extension.md) + - [Automated Testing with a Custom Driver](tutorial/automated-testing-with-a-custom-driver.md) +- [Distribution](tutorial/application-distribution.md) + - [Supported Platforms](tutorial/support.md#supported-platforms) + - [Code Signing](tutorial/code-signing.md) + - [Mac App Store](tutorial/mac-app-store-submission-guide.md) + - [Windows Store](tutorial/windows-store-guide.md) + - [Snapcraft](tutorial/snapcraft.md) +- [Security](tutorial/security.md) + - [Reporting Security Issues](tutorial/security.md#reporting-security-issues) + - [Chromium Security Issues and Upgrades](tutorial/security.md#chromium-security-issues-and-upgrades) + - [NodeGui Security Warnings](tutorial/security.md#NodeGui-security-warnings) + - [Security Checklist](tutorial/security.md#checklist-security-recommendations) +- [Updates](tutorial/updates.md) + - [Deploying an Update Server](tutorial/updates.md#deploying-an-update-server) + - [Implementing Updates in Your App](tutorial/updates.md#implementing-updates-in-your-app) + - [Applying Updates](tutorial/updates.md#applying-updates) +- [Getting Support](tutorial/support.md) + +## Detailed Tutorials + +These individual tutorials expand on topics discussed in the guide above. + +- [Installing NodeGui](tutorial/installation.md) + - [Proxies](tutorial/installation.md#proxies) + - [Custom Mirrors and Caches](tutorial/installation.md#custom-mirrors-and-caches) + - [Troubleshooting](tutorial/installation.md#troubleshooting) +- NodeGui Releases & Developer Feedback + - [Versioning Policy](tutorial/NodeGui-versioning.md) + - [Release Timelines](tutorial/NodeGui-timelines.md) + - [App Feedback Program](tutorial/app-feedback-program.md) +- [Packaging App Source Code with asar](tutorial/application-packaging.md) + - [Generating asar Archives](tutorial/application-packaging.md#generating-asar-archives) + - [Using asar Archives](tutorial/application-packaging.md#using-asar-archives) + - [Limitations](tutorial/application-packaging.md#limitations-of-the-node-api) + - [Adding Unpacked Files to asar Archives](tutorial/application-packaging.md#adding-unpacked-files-to-asar-archives) +- [Testing Widevine CDM](tutorial/testing-widevine-cdm.md) +- [Using Pepper Flash Plugin](tutorial/using-pepper-flash-plugin.md) + +--- + +- [Glossary of Terms](glossary.md) + +## API References + +- [Synopsis](api/synopsis.md) +- [Process Object](api/process.md) +- [Supported Chrome Command Line Switches](api/chrome-command-line-switches.md) +- [Environment Variables](api/environment-variables.md) +- [Breaking API Changes](api/breaking-changes.md) + +### Custom DOM Elements: + +- [`File` Object](api/file-object.md) +- [`` Tag](api/webview-tag.md) +- [`window.open` Function](api/window-open.md) +- [`BrowserWindowProxy` Object](api/browser-window-proxy.md) + +### Modules for the Main Process: + +- [app](api/app.md) +- [autoUpdater](api/auto-updater.md) +- [BrowserView](api/browser-view.md) +- [BrowserWindow](api/browser-window.md) +- [contentTracing](api/content-tracing.md) +- [dialog](api/dialog.md) +- [globalShortcut](api/global-shortcut.md) +- [inAppPurchase](api/in-app-purchase.md) +- [ipcMain](api/ipc-main.md) +- [Menu](api/menu.md) +- [MenuItem](api/menu-item.md) +- [net](api/net.md) +- [netLog](api/net-log.md) +- [powerMonitor](api/power-monitor.md) +- [powerSaveBlocker](api/power-save-blocker.md) +- [protocol](api/protocol.md) +- [screen](api/screen.md) +- [session](api/session.md) +- [systemPreferences](api/system-preferences.md) +- [TouchBar](api/touch-bar.md) +- [Tray](api/tray.md) +- [webContents](api/web-contents.md) + +### Modules for the Renderer Process (Web Page): + +- [desktopCapturer](api/desktop-capturer.md) +- [ipcRenderer](api/ipc-renderer.md) +- [remote](api/remote.md) +- [webFrame](api/web-frame.md) + +### Modules for Both Processes: + +- [clipboard](api/clipboard.md) +- [crashReporter](api/crash-reporter.md) +- [nativeImage](api/native-image.md) +- [shell](api/shell.md) + +## Development + +See [development/README.md](development/README.md) diff --git a/extras/docs/tutorial/development-environment.md b/extras/docs/tutorial/development-environment.md new file mode 100644 index 000000000..6a588d04d --- /dev/null +++ b/extras/docs/tutorial/development-environment.md @@ -0,0 +1,89 @@ +# Developer Environment + +NodeGui development is essentially Node.js development. To turn your operating +system into an environment capable of building desktop apps with NodeGui, +you will merely need Node.js, npm, a code editor of your choice, and a +rudimentary understanding of your operating system's command line client. + +## Setting up macOS + +> NodeGui supports macOS 10.10 (Yosemite) and up. NodeGui currently only supports 64bit OS. + +Currently supported Node.Js versions are 12.x and up. + +We strongly suggest you use some kind of version manager for Node.Js. This would allow you to switch to any version of nodejs quite easily. We recommend `nvm`: https://github.com/nvm-sh/nvm + +Confirm that both `node` and `npm` are available by running: + +```sh +# This command should print the version of Node.js +node -v + +# This command should print the version of npm +npm -v +``` + +If both commands printed a version number, you are all set! Before you get +started, you might want to install a [code editor](#a-good-editor) suited +for JavaScript development. + +## Setting up Windows + +> NodeGui supports Windows 7 and later versions – attempting to develop NodeGui +> applications on earlier versions of Windows might not work. NodeGui currently only supports 64bit OS. + +Currently supported Node.Js versions are 12.x and up. + +We strongly suggest you use some kind of version manager for Node.Js. This would allow you to switch to any version of nodejs quite easily. We recommend `nvm`: https://github.com/nvm-sh/nvm + +We strongly recommend Powershell as preferred terminal in Windows. + +Confirm that both `node` and `npm` are available by running: + +```powershell +# This command should print the version of Node.js +node -v + +# This command should print the version of npm +npm -v +``` + +If both commands printed a version number, you are all set! Before you get +started, you might want to install a [code editor](#a-good-editor) suited +for JavaScript development. + +## Setting up Linux + +> NodeGui currently supports Ubuntu 12.04 and Debian 8 and up. Although other linux distributions can also be easily supported. NodeGui currently only supports 64bit OS. + +Currently supported Node.Js versions are 12.x and up. + +We strongly suggest you use some kind of version manager for Node.Js. This would allow you to switch to any version of nodejs quite easily. We recommend `nvm`: https://github.com/nvm-sh/nvm + +We strongly recommend Powershell as preferred terminal in Windows. + +Confirm that both `node` and `npm` are available by running: + +```sh +# This command should print the version of Node.js +node -v + +# This command should print the version of npm +npm -v +``` + +If both commands printed a version number, you are all set! Before you get +started, you might want to install a [code editor](#a-good-editor) suited +for JavaScript development. + +## A Good Editor + +We might suggest two free popular editors built in NodeGui: +GitHub's [Atom][atom] and Microsoft's [Visual Studio Code][code]. Both of +them have excellent JavaScript support. + +If you are one of the many developers with a strong preference, know that +virtually all code editors and IDEs these days support JavaScript. + +[code]: https://code.visualstudio.com/ +[atom]: https://atom.io/ diff --git a/extras/docs/tutorial/first-app.md b/extras/docs/tutorial/first-app.md new file mode 100644 index 000000000..207e8bd50 --- /dev/null +++ b/extras/docs/tutorial/first-app.md @@ -0,0 +1,117 @@ +# Writing Your First NodeGui App + +NodeGui enables you to create desktop applications with pure JavaScript. You could see it +as a lightly modified variant of the Node.js runtime that is focused on desktop applications +instead of web servers. + +NodeGui is also an efficient JavaScript binding to a cross platform graphical user interface +(GUI) library `Qt`. Qt is one of the most mature and efficient library for building desktop applications. +This enabled NodeGui to be extrememly memory and CPU efficient as compared to other popular Javascript Desktop GUI solutions. A hello world app built with NodeGui runs on less than 20Mb of memory. + +## Hello World + +Clone and run the code in this tutorial by using the +[`nodegui/nodegui-quick-start`][quick-start] repository. + +**Note**: Running this requires [Git](https://git-scm.com) and [npm](https://www.npmjs.com/). + +```sh +# Clone the repository +$ git clone https://github.com/nodegui/nodegui-quick-start +# Go into the repository +$ cd nodegui-quick-start +# Install dependencies +$ npm install +# Run the app +$ npm start +``` + +As far as development is concerned, an NodeGui application is essentially a +Node.js application. The starting point is a `package.json` that is identical +to that of a Node.js module. A most basic NodeGui app would have the following +folder structure: + +```text +your-app/ +├── package.json +├── index.js +``` + +## NodeGui Development in a Nutshell + +NodeGui apps are developed in JavaScript using the same principles and methods +found in Node.js development. All APIs and features found in NodeGui are +accessible through the `@nodegui/nodegui` module, which can be required like any other +Node.js module: + +```javascript +require("@nodegui/nodegui"); +``` + +The `@nodegui/nodegui` module exports features in namespaces. As examples, windows can be created +using the `QMainWindow` class. A simple `main.js` file might open a window: + +```javascript +const { + QMainWindow, + QWidget, + QLabel, + FlexLayout +} = require("@nodegui/nodegui"); + +const win = new QMainWindow(); +//------------------------------- +const centralWidget = new QWidget(); +centralWidget.setObjectName("myroot"); +const rootLayout = new FlexLayout(); +centralWidget.setLayout(rootLayout); +//-------------------------------------- +const label = new QLabel(); +label.setObjectName("mylabel"); +label.setText("Hello World"); +//-------------------------------------- +rootLayout.addWidget(label); +win.setCentralWidget(centralWidget); +win.setStyleSheet( + ` + #myroot { + background-color: #009688; + } + #mylabel { + font-size: 16px; + font-weight: bold; + } + ` +); +win.show(); + +global.win = win; // To prevent win from being garbage collected. +``` + +The `index.js` should create windows and handle all the system events your +application might encounter. + +## Running Your App + +You can try your app by running `npm start` from your application's +directory. + +## Trying this Example + +Clone and run the code in this tutorial by using the +[`nodegui/nodegui-quick-start`][quick-start] repository. + +**Note**: Running this requires [Git](https://git-scm.com) and [npm](https://www.npmjs.com/). + +```sh +# Clone the repository +$ git clone https://github.com/nodegui/nodegui-quick-start +# Go into the repository +$ cd nodegui-quick-start +# Install dependencies +$ npm install +# Run the app +$ npm start +``` + +[quick-start]: https://github.com/nodegui/nodegui-quick-start diff --git a/src/lib/QtGui/QWidget/index.ts b/src/lib/QtGui/QWidget/index.ts index addf65bea..0275ba1d4 100644 --- a/src/lib/QtGui/QWidget/index.ts +++ b/src/lib/QtGui/QWidget/index.ts @@ -2,6 +2,7 @@ import addon from "../../core/addon"; import { NodeLayout } from "../../QtWidgets/QLayout"; import { EventWidget, BaseWidgetEvents } from "../../core/EventWidget"; import { NativeElement } from "../../core/Component"; +import { FlexLayout } from "../../core/FlexLayout"; // All Widgets should extend from NodeWidget // Implement all native QWidget methods here so that all widgets get access to those aswell @@ -18,6 +19,11 @@ export abstract class NodeWidget extends EventWidget { this.native.close(); }; setLayout = (parentLayout: NodeLayout) => { + const flexLayout = parentLayout as FlexLayout; + if (flexLayout.setFlexNode) { + //if flex layout set the flexnode + flexLayout.setFlexNode(this.getFlexNode()); + } this.native.setLayout(parentLayout.native); this.layout = parentLayout; };