Merge branch 'feature/tab' into feature/QTabWidgetV2

This commit is contained in:
Atul R 2019-09-20 23:20:07 +02:00 committed by GitHub
commit 8350747af2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 722 additions and 108 deletions

View File

@ -85,6 +85,42 @@
"contributions": [
"code"
]
},
{
"login": "soonoo",
"name": "Soonwoo Hong",
"avatar_url": "https://avatars2.githubusercontent.com/u/5436405?v=4",
"profile": "https://github.com/soonoo",
"contributions": [
"code"
]
},
{
"login": "illBeRoy",
"name": "Roy Sommer",
"avatar_url": "https://avatars2.githubusercontent.com/u/6681893?v=4",
"profile": "https://github.com/illBeRoy",
"contributions": [
"code"
]
},
{
"login": "paulocoghi",
"name": "Paulo Coghi",
"avatar_url": "https://avatars1.githubusercontent.com/u/378397?v=4",
"profile": "https://github.com/paulocoghi",
"contributions": [
"ideas"
]
},
{
"login": "balthild",
"name": "Balthild Ires",
"avatar_url": "https://avatars2.githubusercontent.com/u/2662758?v=4",
"profile": "https://balthild.com",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,

32
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,32 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. Mac, Linux, Win]
- NodeGUI version
- OS Version
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -1,7 +1,7 @@
# NodeGUI
[![Join the NodeGUI community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/nodegui)
[![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors)
[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors)
Build **performant**, **native** and **cross-platform** desktop applications with **JavaScript** + powerful **CSS like styling**.🚀
@ -70,15 +70,23 @@ Looking to contribute? If you wish to implement a new widget/add more features a
`npm run build [--qt_home_dir=/path/to/qt]`
### LICENSE
## Funding
NodeGUI is an open source project and requires your support. If you like this project, please consider supporting my work with Ko-fi. Alternatively, Issues on NodeGui can be funded by anyone via Issuehunt and the amount will be distributed to respective contributors.
<p>
<a href='https://ko-fi.com/E1E510AV9' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi4.png?v=2' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a> &nbsp; &nbsp;
<a href="https://issuehunt.io/r/nodegui/nodegui"><img alt="issuehunt" src="https://github.com/BoostIO/issuehunt-materials/raw/master/v1/issuehunt-button-v1.svg?sanitize=true" height="30px" /></a>
</p>
## Special Thanks
- [Logo: Thanks to Vishwas Shetty from the Noun Project.](https://github.com/nodegui/nodegui/blob/master/extras/legal/logo/thanks.md)
## License
MIT
## Note
> Since we do not in any way modify the code of Qt and only link to it dynamically, I believe 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 purposes (provided you abide by MIT License).
## Maintainers ✨
@ -91,6 +99,7 @@ People maintaining this project.
</tr>
</table>
## Contributors ✨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
@ -110,6 +119,10 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<tr>
<td align="center"><a href="http://www.mad3linux.org"><img src="https://avatars3.githubusercontent.com/u/508624?v=4" width="100px;" alt="Átila Camurça Alves"/><br /><sub><b>Átila Camurça Alves</b></sub></a><br /><a href="https://github.com/nodegui/nodegui/commits?author=atilacamurca" title="Documentation">📖</a></td>
<td align="center"><a href="http://hibbard.eu"><img src="https://avatars2.githubusercontent.com/u/1940994?v=4" width="100px;" alt="James Hibbard"/><br /><sub><b>James Hibbard</b></sub></a><br /><a href="https://github.com/nodegui/nodegui/commits?author=jameshibbard" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/soonoo"><img src="https://avatars2.githubusercontent.com/u/5436405?v=4" width="100px;" alt="Soonwoo Hong"/><br /><sub><b>Soonwoo Hong</b></sub></a><br /><a href="https://github.com/nodegui/nodegui/commits?author=soonoo" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/illBeRoy"><img src="https://avatars2.githubusercontent.com/u/6681893?v=4" width="100px;" alt="Roy Sommer"/><br /><sub><b>Roy Sommer</b></sub></a><br /><a href="https://github.com/nodegui/nodegui/commits?author=illBeRoy" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/paulocoghi"><img src="https://avatars1.githubusercontent.com/u/378397?v=4" width="100px;" alt="Paulo Coghi"/><br /><sub><b>Paulo Coghi</b></sub></a><br /><a href="#ideas-paulocoghi" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center"><a href="https://balthild.com"><img src="https://avatars2.githubusercontent.com/u/2662758?v=4" width="100px;" alt="Balthild Ires"/><br /><sub><b>Balthild Ires</b></sub></a><br /><a href="https://github.com/nodegui/nodegui/commits?author=balthild" title="Code">💻</a></td>
</tr>
</table>

View File

@ -11,6 +11,7 @@
"../src/cpp/core/YogaWidget/yogawidget.cpp",
# wrapped cpps. Move non wrapped ones to shared gypi
"../src/cpp/QtGui/QApplication/qapplication_wrap.cpp",
"../src/cpp/QtGui/QClipboard/qclipboard_wrap.cpp",
"../src/cpp/QtGui/QEvent/QKeyEvent/qkeyevent_wrap.cpp",
"../src/cpp/QtGui/QPixmap/qpixmap_wrap.cpp",
"../src/cpp/QtGui/QIcon/qicon_wrap.cpp",

1
docs/CNAME Normal file
View File

@ -0,0 +1 @@
docs.nodegui.org

View File

@ -53,6 +53,8 @@
- [FlexLayout](api/FlexLayout.md)
- [QPixmap](api/QPixmap.md)
- [QIcon](api/QIcon.md)
- [QCursor](api/QCursor.md)
- [QClipboard](api/QClipboard.md)
- [Qt Enums](api/QtEnums.md)
### Internal Modules

View File

@ -21,10 +21,14 @@ qApp.quit();
QApplication can access all the static methods defined in [Component](api/Component.md). Additionally it also has the following static methods.
#### `qApp.instance()`
#### `QApplication.instance()`
Returns the already initialised QApplication instance. It calls the native method [QApplication: instance](https://doc.qt.io/qt-5/qcoreapplication.html#instance).
#### `QApplication.clipboard()`
Returns the object for interacting with the clipboard. It calls the native method [QApplication: clipboard](https://doc.qt.io/qt-5/qguiapplication.html#clipboard). See QClipboard.
### Instance Properties
QApplication can access all the instance properties defined in [Component](api/Component.md)

52
docs/api/QClipboard.md Normal file
View File

@ -0,0 +1,52 @@
## Class: QClipboard
> The QClipboard class provides access to the window system clipboard.
**This class is a JS wrapper around Qt's [QClipboard class](https://doc.qt.io/qt-5/QClipboard.html)**
**QClipboard inherits from [Component](api/Component.md)**
### Example
```javascript
const {
QClipboard,
QClipboardMode,
QApplication
} = require("@nodegui/nodegui");
const clipboard = QApplication.clipboard();
const text = clipboard.text(QClipboardMode.Clipboard);
```
### Static Methods
QClipboard can access all the static methods defined in [Component](api/Component.md)
### Instance Properties
QClipboard can access all the instance properties defined in [Component](api/Component.md)
### Instance Methods
QClipboard can access all the instance methods defined in [Component](api/Component.md). Additionally it has:
### `clipboard.clear(mode)`
Clear the clipboard contents. It calls the native method [QClipboard: clear](https://doc.qt.io/qt-5/qclipboard.html#clear).
- `mode` - This enum type is used to control which part of the system clipboard is used. See https://doc.qt.io/qt-5/qclipboard.html#Mode-enum
### `clipboard.setText(text, mode)`
Copies text into the clipboard as plain text. It calls the native method [QClipboard: setText](https://doc.qt.io/qt-5/qclipboard.html#setText).
- `text` - The text you want to copy to clipboard.
- `mode` - This enum type is used to control which part of the system clipboard is used. See https://doc.qt.io/qt-5/qclipboard.html#Mode-enum
### `clipboard.text(mode)`
Returns the clipboard text as plain text, or an empty string if the clipboard does not contain any text. It calls the native method [QClipboard: text](https://doc.qt.io/qt-5/qclipboard.html#text).
- `mode` - This enum type is used to control which part of the system clipboard is used. See https://doc.qt.io/qt-5/qclipboard.html#Mode-enum

View File

@ -30,3 +30,14 @@ QIcon can access all the instance properties defined in [Component](api/Componen
### Instance Methods
QIcon can access all the instance methods defined in [Component](api/Component.md)
Additionally it also has the following instance methods:
#### `icon.pixmap(width, height, mode?, state?)`
Returns a pixmap with the requested size, mode, and state, generating one if necessary. The pixmap might be smaller than requested, but never larger.
. It calls the native method [QIcon: pixmap](https://doc.qt.io/qt-5/qicon.html#pixmap-3).
- `width`: number,
- `height`: number
- `mode?`: QIconMode
- `state?`: QIconState

View File

@ -28,24 +28,54 @@ QPlainTextEdit can access all the static methods defined in [NodeWidget](api/Nod
QPlainTextEdit can access all the instance properties defined in [NodeWidget](api/NodeWidget.md).
#### `plainTextEdit.placeholderText`
The placeholder text set on the plainTextEdit.
### Instance Methods
QPlainTextEdit can access all the instance methods defined in [NodeWidget](api/NodeWidget.md).
#### [`plainTextEdit.setPlainText(text)`](https://doc.qt.io/qt-5/qplaintextedit.html#setPlainText)
#### `plainTextEdit.setPlainText(text)`
Sets the given text to the plainTextEdit.
Sets the given text to the plainTextEdit. It calls the native method [QPlainTextEdit: setPlainText](https://doc.qt.io/qt-5/qplaintextedit.html#setPlainText).
- `text` string
#### [`plainTextEdit.toPlainText()`](https://doc.qt.io/qt-5/qplaintextedit.html#toPlainText)
#### `plainTextEdit.setPlaceholderText(text)`
Returns the text of the text edit as plain text.
Sets the given text to the plainTextEdit's placeholder.
#### [`plainTextEdit.setReadOnly(isReadOnly)`](https://doc.qt.io/qt-5/qplaintextedit.html#readOnly-prop)
- `text` string
Sets the plainTextEdit to be read only.
#### `plainTextEdit.toPlainText()`
#### [`plainTextEdit.clear()`](https://doc.qt.io/qt-5/qplaintextedit.html#clear)
Returns the text of the text edit as plain text. [QPlainTextEdit: toPlainText](https://doc.qt.io/qt-5/qplaintextedit.html#toPlainText).
Deletes all the text in the text edit.
#### `plainTextEdit.setReadOnly(isReadOnly)`
Sets the plainTextEdit to be read only. [QPlainTextEdit: isReadOnly](https://doc.qt.io/qt-5/qplaintextedit.html#readOnly-prop).
#### `plainTextEdit.clear()`
Deletes all the text in the text edit.[QPlainTextEdit: clear](https://doc.qt.io/qt-5/qplaintextedit.html#clear).
#### `plainTextEdit.setWordWrapMode(mode)`
This property holds the mode QPlainTextEdit will use when wrapping text by words.[QPlainTextEdit: setWordWrapMode](https://doc.qt.io/qt-5/qplaintextedit.html#wordWrapMode-prop).
- mode: QTextOptionWrapMode
#### `plainTextEdit.wordWrapMode()`
returns word wrap mode. [QPlainTextEdit: wordWrapMode](https://doc.qt.io/qt-5/qplaintextedit.html#wordWrapMode-prop).
#### `plainTextEdit.setLineWrapMode(mode)`
This property holds the line wrap mode. [QPlainTextEdit: setLineWrapMode](https://doc.qt.io/qt-5/qplaintextedit.html#lineWrapMode-prop).
- mode: LineWrapMode
#### `plainTextEdit.lineWrapMode()`
returns line wrap mode. [QPlainTextEdit: setLineWrapMode](https://doc.qt.io/qt-5/qplaintextedit.html#lineWrapMode-prop).

View File

@ -1,6 +1,6 @@
# Logo
<img alt="logo" src="https://github.com/nodegui/nodegui/raw/master/extras/logo/logo.png" height="400" />
<img alt="logo" src="https://raw.githubusercontent.com/nodegui/nodegui/master/extras/logo/nodegui.png" height="400" />
Special thanks to the Noun Project for the logo.

48
package-lock.json generated
View File

@ -1,13 +1,13 @@
{
"name": "@nodegui/nodegui",
"version": "0.1.7",
"version": "0.1.9",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@nodegui/qode": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@nodegui/qode/-/qode-1.0.4.tgz",
"integrity": "sha512-CEEAI1mJ+4eH6G2OlNtn75vUxTBw/06IcEkXlwkDMI/mU5iE52WHToybYba77gOeoxrGx3uIwkfWRV2LRVyp/Q==",
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@nodegui/qode/-/qode-1.0.5.tgz",
"integrity": "sha512-JKb4JcC03VCdodmiL35VfznsCKHpiKOYbtgf9+KTHhH5p7IXvr+0k/LIq112T6Rpxd5zXa1pbsnfa2F8ReyWEg==",
"requires": {
"env-paths": "^2.2.0",
"extract-zip": "^1.6.7",
@ -975,21 +975,28 @@
"integrity": "sha512-2+DuKodWvwRTrCfKOeR24KIc5unKjOh8mz17NCzVnHWfjAdDqbfbjqh7gUT+BkXBRQM52+xCHciKWonJ3CbJMQ=="
},
"node-gyp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz",
"integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==",
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.0.3.tgz",
"integrity": "sha512-z/JdtkFGUm0QaQUusvloyYuGDub3nUbOo5de1Fz57cM++osBTvQatBUSTlF1k/w8vFHPxxXW6zxGvkxXSpaBkQ==",
"requires": {
"env-paths": "^1.0.0",
"glob": "^7.0.3",
"graceful-fs": "^4.1.2",
"mkdirp": "^0.5.0",
"nopt": "2 || 3",
"npmlog": "0 || 1 || 2 || 3 || 4",
"osenv": "0",
"request": "^2.87.0",
"rimraf": "2",
"semver": "~5.3.0",
"tar": "^4.4.8",
"which": "1"
},
"dependencies": {
"env-paths": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz",
"integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA="
}
}
},
"nopt": {
@ -1054,25 +1061,6 @@
"wrappy": "1"
}
},
"os-homedir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
},
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
},
"osenv": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
"requires": {
"os-homedir": "^1.0.0",
"os-tmpdir": "^1.0.0"
}
},
"p-cancelable": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
@ -1163,9 +1151,9 @@
"dev": true
},
"psl": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz",
"integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag=="
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.3.1.tgz",
"integrity": "sha512-2KLd5fKOdAfShtY2d/8XDWVRnmp3zp40Qt6ge2zBPFARLXOGUf2fHD5eg+TV/5oxBtQKVhjUaKFsAaE4HnwfSA=="
},
"pump": {
"version": "3.0.0",

View File

@ -1,6 +1,6 @@
{
"name": "@nodegui/nodegui",
"version": "0.1.7",
"version": "0.1.9",
"description": "A cross platform library to build native desktop apps.",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
@ -26,10 +26,10 @@
"docs": "serve docs"
},
"dependencies": {
"@nodegui/qode": "^1.0.4",
"@nodegui/qode": "^1.0.5",
"cuid": "^2.1.6",
"node-addon-api": "^1.6.3",
"node-gyp": "^4.0.0",
"node-gyp": "^5.0.3",
"postcss-nodegui-autoprefixer": "0.0.7"
},
"devDependencies": {

View File

@ -1,6 +1,7 @@
const path = require("path");
const fs = require("fs");
const childProcess = require("child_process");
const { qtHome } = require("@nodegui/qode");
const ROOT_DIR = path.resolve(__dirname, "../");
const MOC_AUTOGEN_DIR = path.resolve(ROOT_DIR, "src/cpp/autogen");
@ -50,13 +51,22 @@ const main = () => {
eachHeaderPath,
includeFilePath
);
console.log(command);
childProcess.exec(command, {}, error => {
if (error) {
console.error(`exec error: ${error}`);
return;
const mocPath = path.resolve(process.env.QT_INSTALL_DIR || qtHome, "bin");
childProcess.exec(
command,
{
env: {
...process.env,
PATH: `${mocPath}${path.delimiter}${process.env.PATH}`
}
},
error => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
}
});
);
return outfilePath;
});
generateMocGypiFile(outFiles);

View File

@ -1,6 +1,7 @@
#include "qapplication_wrap.h"
#include "src/cpp/core/Component/component_macro.h"
#include "src/cpp/Extras/Utils/nutils.h"
#include "src/cpp/QtGui/QClipboard/qclipboard_wrap.h"
Napi::FunctionReference QApplicationWrap::constructor;
int QApplicationWrap::argc = 0;
@ -15,6 +16,7 @@ Napi::Object QApplicationWrap::init(Napi::Env env, Napi::Object exports)
InstanceMethod("exec", &QApplicationWrap::exec),
InstanceMethod("quit", &QApplicationWrap::quit),
StaticMethod("instance", &StaticQApplicationWrapMethods::instance),
StaticMethod("clipboard", &StaticQApplicationWrapMethods::clipboard),
COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE
});
constructor = Napi::Persistent(func);
@ -28,22 +30,24 @@ QApplicationWrap::QApplicationWrap(const Napi::CallbackInfo& info)
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
if(info.Length() == 1) {
this->instance = std::unique_ptr<QApplication>(info[0].As<Napi::External<QApplication>>().Data());
this->instance = info[0].As<Napi::External<QApplication>>().Data();
} else if (info.Length() == 0){
this->instance = std::make_unique<QApplication>(this->argc, this->argv);
this->instance = new QApplication(this->argc, this->argv);
this->_wasManuallyCreated = true;
} else {
Napi::TypeError::New(env, "Wrong number of arguments").ThrowAsJavaScriptException();
}
}
QApplicationWrap::~QApplicationWrap()
{
this->instance.reset();
if(this->_wasManuallyCreated){
delete this->instance;
}
}
QApplication* QApplicationWrap::getInternalInstance()
{
return this->instance.get();
return this->instance;
}
Napi::Value QApplicationWrap::processEvents(const Napi::CallbackInfo& info)
@ -87,3 +91,11 @@ Napi::Value StaticQApplicationWrapMethods::instance(const Napi::CallbackInfo& in
Napi::Object instance = QApplicationWrap::constructor.New({ Napi::External<QApplication>::New(env, app) });
return instance;
}
Napi::Value StaticQApplicationWrapMethods::clipboard(const Napi::CallbackInfo& info)
{
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
QClipboard* clipboard = QApplication::clipboard();
return QClipboardWrap::constructor.New({ Napi::External<QClipboard>::New(env, clipboard) });
}

View File

@ -1,15 +1,15 @@
#pragma once
#include <napi.h>
#include <stdlib.h>
#include <QApplication>
class QApplicationWrap : public Napi::ObjectWrap<QApplicationWrap> {
private:
std::unique_ptr<QApplication> instance;
QApplication* instance;
static int argc;
static char** argv;
bool _wasManuallyCreated = false;
public:
static Napi::FunctionReference constructor;
@ -26,4 +26,5 @@ public:
namespace StaticQApplicationWrapMethods {
Napi::Value instance(const Napi::CallbackInfo& info);
Napi::Value clipboard(const Napi::CallbackInfo& info);
}

View File

@ -0,0 +1,63 @@
#include "qclipboard_wrap.h"
#include "src/cpp/Extras/Utils/nutils.h"
#include "deps/spdlog/spdlog.h"
Napi::FunctionReference QClipboardWrap::constructor;
Napi::Object QClipboardWrap::init(Napi::Env env, Napi::Object exports)
{
Napi::HandleScope scope(env);
char CLASSNAME[] = "QClipboard";
Napi::Function func = DefineClass(env, CLASSNAME, {
InstanceMethod("clear", &QClipboardWrap::clear),
InstanceMethod("setText", &QClipboardWrap::setText),
InstanceMethod("text", &QClipboardWrap::text),
COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE
});
constructor = Napi::Persistent(func);
exports.Set(CLASSNAME, func);
return exports;
}
QClipboardWrap::QClipboardWrap(const Napi::CallbackInfo &info) : Napi::ObjectWrap<QClipboardWrap>(info)
{
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
if (info[0].IsExternal()) {
this->instance = info[0].As<Napi::External<QClipboard>>().Data();
}
else {
Napi::TypeError::New(env, "Incorrect initialization of QClipboardWrap").ThrowAsJavaScriptException();
}
}
QClipboard *QClipboardWrap::getInternalInstance()
{
return this->instance;
}
Napi::Value QClipboardWrap::clear(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
Napi::Number mode = info[0].As<Napi::Number>();
this->instance->clear(static_cast<QClipboard::Mode>(mode.Int32Value()));
return env.Null();
}
Napi::Value QClipboardWrap::setText(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
Napi::String text = info[0].As<Napi::String>();
Napi::Number mode = info[1].As<Napi::Number>();
QString clipboardText = text.Utf8Value().c_str();
this->instance->setText(clipboardText, static_cast<QClipboard::Mode>(mode.Int32Value()));
return env.Null();
}
Napi::Value QClipboardWrap::text(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
Napi::Number mode = info[0].As<Napi::Number>();
QString text = this->instance->text(static_cast<QClipboard::Mode>(mode.Int32Value()));
return Napi::Value::From(env, text.toStdString());
}

View File

@ -0,0 +1,20 @@
#pragma once
#include <napi.h>
#include <QClipboard>
#include "src/cpp/core/Component/component_macro.h"
class QClipboardWrap : public Napi::ObjectWrap<QClipboardWrap>
{
private:
QClipboard* instance;
public:
static Napi::FunctionReference constructor;
static Napi::Object init(Napi::Env env, Napi::Object exports);
QClipboardWrap(const Napi::CallbackInfo &info);
QClipboard *getInternalInstance();
// Wrapped methods
Napi::Value clear(const Napi::CallbackInfo& info);
Napi::Value setText(const Napi::CallbackInfo& info);
Napi::Value text(const Napi::CallbackInfo& info);
};

View File

@ -1,4 +1,5 @@
#include "qicon_wrap.h"
#include "src/cpp/QtGui/QPixmap/qpixmap_wrap.h"
#include "src/cpp/Extras/Utils/nutils.h"
#include "deps/spdlog/spdlog.h"
@ -9,6 +10,7 @@ Napi::Object QIconWrap::init(Napi::Env env, Napi::Object exports)
Napi::HandleScope scope(env);
char CLASSNAME[] = "QIcon";
Napi::Function func = DefineClass(env, CLASSNAME, {
InstanceMethod("pixmap", &QIconWrap::pixmap),
COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE
});
constructor = Napi::Persistent(func);
@ -45,3 +47,30 @@ QIcon *QIconWrap::getInternalInstance()
{
return this->instance.get();
}
Napi::Value QIconWrap::pixmap(const Napi::CallbackInfo& info)
{
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
Napi::Number widthValue = info[0].As<Napi::Number>();
Napi::Number heightValue = info[1].As<Napi::Number>();
int width = widthValue.Int32Value();
int height = heightValue.Int32Value();
QIcon::Mode mode = QIcon::Normal;
if (info.Length() > 2) {
int modeInt = info[2].As<Napi::Number>().Int32Value();
mode = static_cast<QIcon::Mode>(modeInt);
}
QIcon::State state = QIcon::Off;
if (info.Length() > 3) {
int stateInt = info[3].As<Napi::Number>().Int32Value();
state = static_cast<QIcon::State>(stateInt);
}
QPixmap* pixmap = new QPixmap(this->instance->pixmap(width, height, mode, state));
auto instance = QPixmapWrap::constructor.New({ Napi::External<QPixmap>::New(env, pixmap) });
return instance;
}

View File

@ -17,4 +17,5 @@ public:
~QIconWrap();
QIcon *getInternalInstance();
// Wrapped methods
Napi::Value pixmap(const Napi::CallbackInfo& info);
};

View File

@ -2,12 +2,21 @@
#include <QCheckBox>
#include "src/cpp/core/NodeWidget/nodewidget.h"
#include "napi.h"
class NCheckBox: public QCheckBox, public NodeWidget
{
NODEWIDGET_IMPLEMENTATIONS(QCheckBox)
public:
using QCheckBox::QCheckBox; //inherit all constructors of QCheckBox
void connectWidgetSignalsToEventEmitter() {
QObject::connect(this, &QCheckBox::toggled, [=](bool checked) {
Napi::Env env = this->emitOnNode.Env();
Napi::HandleScope scope(env);
this->emitOnNode.Call({ Napi::String::New(env, "toggled"), Napi::Value::From(env, checked) });
});
}
};

View File

@ -9,25 +9,6 @@ class NMainWindow: public QMainWindow, public NodeWidget
NODEWIDGET_IMPLEMENTATIONS(QMainWindow)
public:
using QMainWindow::QMainWindow; //inherit all constructors of QMainWindow
private:
void calculateLayout(){
YGDirection direction = YGNodeStyleGetDirection(this->getFlexNode());
YGNodeCalculateLayout(this->getFlexNode(),width(),height(),direction);
}
bool eventFilter(QObject *object, QEvent *event) { // This will be installed on mainwidgetwrap
switch(event->type()) {
case QEvent::LayoutRequest:
case QEvent::ChildRemoved: {
calculateLayout(); break;
}
default: ; // do nothing
}
return QMainWindow::eventFilter(object, event);
}
void resizeEvent(QResizeEvent * event){
calculateLayout();
QMainWindow::resizeEvent(event);
}
};

View File

@ -17,5 +17,40 @@ public:
Napi::HandleScope scope(env);
this->emitOnNode.Call({Napi::String::New(env, "textChanged")});
});
QObject::connect(this, &QPlainTextEdit::blockCountChanged, [=](int newBlockCount) {
Napi::Env env = this->emitOnNode.Env();
Napi::HandleScope scope(env);
this->emitOnNode.Call({Napi::String::New(env, "blockCountChanged"), Napi::Value::From(env, newBlockCount)});
});
QObject::connect(this, &QPlainTextEdit::copyAvailable, [=](bool yes) {
Napi::Env env = this->emitOnNode.Env();
Napi::HandleScope scope(env);
this->emitOnNode.Call({Napi::String::New(env, "copyAvailable"), Napi::Value::From(env, yes)});
});
QObject::connect(this, &QPlainTextEdit::cursorPositionChanged, [=]() {
Napi::Env env = this->emitOnNode.Env();
Napi::HandleScope scope(env);
this->emitOnNode.Call({Napi::String::New(env, "cursorPositionChanged")});
});
QObject::connect(this, &QPlainTextEdit::modificationChanged, [=](bool charged) {
Napi::Env env = this->emitOnNode.Env();
Napi::HandleScope scope(env);
this->emitOnNode.Call({Napi::String::New(env, "modificationChanged"), Napi::Value::From(env, charged)});
});
QObject::connect(this, &QPlainTextEdit::redoAvailable, [=](bool available) {
Napi::Env env = this->emitOnNode.Env();
Napi::HandleScope scope(env);
this->emitOnNode.Call({Napi::String::New(env, "redoAvailable"), Napi::Value::From(env, available)});
});
QObject::connect(this, &QPlainTextEdit::selectionChanged, [=]() {
Napi::Env env = this->emitOnNode.Env();
Napi::HandleScope scope(env);
this->emitOnNode.Call({Napi::String::New(env, "selectionChanged")});
});
QObject::connect(this, &QPlainTextEdit::undoAvailable, [=](bool available) {
Napi::Env env = this->emitOnNode.Env();
Napi::HandleScope scope(env);
this->emitOnNode.Call({Napi::String::New(env, "undoAvailable"), Napi::Value::From(env, available)});
});
}
};

View File

@ -12,9 +12,14 @@ Napi::Object QPlainTextEditWrap::init(Napi::Env env, Napi::Object exports) {
char CLASSNAME[] = "QPlainTextEdit";
Napi::Function func = DefineClass(env, CLASSNAME, {
InstanceMethod("setPlainText",&QPlainTextEditWrap::setPlainText),
InstanceMethod("setPlaceholderText",&QPlainTextEditWrap::setPlaceholderText),
InstanceMethod("toPlainText",&QPlainTextEditWrap::toPlainText),
InstanceMethod("setReadOnly", &QPlainTextEditWrap::setReadOnly),
InstanceMethod("clear", &QPlainTextEditWrap::clear),
InstanceMethod("setWordWrapMode", &QPlainTextEditWrap::setWordWrapMode),
InstanceMethod("wordWrapMode", &QPlainTextEditWrap::wordWrapMode),
InstanceMethod("setLineWrapMode", &QPlainTextEditWrap::setLineWrapMode),
InstanceMethod("lineWrapMode", &QPlainTextEditWrap::lineWrapMode),
QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QPlainTextEditWrap)
QABSTRACTSCROLLAREA_WRAPPED_METHODS_EXPORT_DEFINE(QPlainTextEditWrap)
});
@ -56,6 +61,14 @@ Napi::Value QPlainTextEditWrap::setPlainText(const Napi::CallbackInfo& info){
return env.Null();
}
Napi::Value QPlainTextEditWrap::setPlaceholderText(const Napi::CallbackInfo& info){
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
Napi::String text = info[0].As<Napi::String>();
this->instance->setPlaceholderText(text.Utf8Value().c_str());
return env.Null();
}
Napi::Value QPlainTextEditWrap::setReadOnly(const Napi::CallbackInfo &info)
{
Napi::Env env = info.Env();
@ -77,3 +90,33 @@ Napi::Value QPlainTextEditWrap::clear(const Napi::CallbackInfo &info){
this->instance->clear();
return env.Null();
}
Napi::Value QPlainTextEditWrap::setWordWrapMode(const Napi::CallbackInfo &info){
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
Napi::Number mode = info[0].As<Napi::Number>();
this->instance->setWordWrapMode(static_cast<QTextOption::WrapMode>(mode.Int32Value()));
return env.Null();
}
Napi::Value QPlainTextEditWrap::wordWrapMode(const Napi::CallbackInfo &info){
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
int value = static_cast<int>(this->instance->wordWrapMode());
return Napi::Number::From(env, value);
}
Napi::Value QPlainTextEditWrap::setLineWrapMode(const Napi::CallbackInfo &info){
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
Napi::Number mode = info[0].As<Napi::Number>();
this->instance->setLineWrapMode(static_cast<QPlainTextEdit::LineWrapMode>(mode.Int32Value()));
return env.Null();
}
Napi::Value QPlainTextEditWrap::lineWrapMode(const Napi::CallbackInfo &info){
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
int value = static_cast<int>(this->instance->lineWrapMode());
return Napi::Number::From(env, value);
}

View File

@ -20,8 +20,13 @@ class QPlainTextEditWrap : public Napi::ObjectWrap<QPlainTextEditWrap>{
QABSTRACTSCROLLAREA_WRAPPED_METHODS_DECLARATION
Napi::Value setPlainText(const Napi::CallbackInfo& info);
Napi::Value setPlaceholderText(const Napi::CallbackInfo& info);
Napi::Value toPlainText(const Napi::CallbackInfo &info);
Napi::Value setReadOnly(const Napi::CallbackInfo &info);
Napi::Value clear(const Napi::CallbackInfo &info);
Napi::Value setWordWrapMode(const Napi::CallbackInfo &info);
Napi::Value wordWrapMode(const Napi::CallbackInfo &info);
Napi::Value setLineWrapMode(const Napi::CallbackInfo &info);
Napi::Value lineWrapMode(const Napi::CallbackInfo &info);
};

View File

@ -46,4 +46,12 @@ Napi::Value QScrollAreaWrap::setWidget(const Napi::CallbackInfo& info) {
QWidgetWrap* contentWidgetWrap = Napi::ObjectWrap<QWidgetWrap>::Unwrap(contentWidget);
this->instance->setWidget(contentWidgetWrap->getInternalInstance());
return env.Null();
}
Napi::Value QScrollAreaWrap::takeWidget(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
this->instance->takeWidget();
// We will not return the value here since we are doing it in js side anyway
return env.Null();
}

View File

@ -17,6 +17,7 @@ class QScrollAreaWrap : public Napi::ObjectWrap<QScrollAreaWrap>{
static Napi::FunctionReference constructor;
//wrapped methods
Napi::Value setWidget(const Napi::CallbackInfo &info);
Napi::Value takeWidget(const Napi::CallbackInfo &info);
QABSTRACTSCROLLAREA_WRAPPED_METHODS_DECLARATION
};

View File

@ -154,6 +154,17 @@ Napi::Value setGeometry(const Napi::CallbackInfo& info){ \
this->instance->setGeometry(x, y, width, height); \
return env.Null(); \
} \
Napi::Value geometry(const Napi::CallbackInfo& info){ \
Napi::Env env = info.Env(); \
Napi::HandleScope scope(env); \
QRect geometry = this->instance->geometry(); \
Napi::Object geometryObj = Napi::Object::New(env); \
geometryObj.Set("width", geometry.width()); \
geometryObj.Set("height", geometry.height()); \
geometryObj.Set("x", geometry.x()); \
geometryObj.Set("y", geometry.y()); \
return geometryObj; \
} \
Napi::Value setMaximumSize(const Napi::CallbackInfo& info){ \
Napi::Env env = info.Env(); \
Napi::HandleScope scope(env); \
@ -263,6 +274,7 @@ Napi::Value setWindowFlag(const Napi::CallbackInfo& info){ \
InstanceMethod("setEnabled",&WidgetWrapName::setEnabled), \
InstanceMethod("setFixedSize",&WidgetWrapName::setFixedSize), \
InstanceMethod("setGeometry",&WidgetWrapName::setGeometry), \
InstanceMethod("geometry",&WidgetWrapName::geometry), \
InstanceMethod("setMaximumSize",&WidgetWrapName::setMaximumSize), \
InstanceMethod("setMinimumSize",&WidgetWrapName::setMinimumSize), \
InstanceMethod("repaint",&WidgetWrapName::repaint), \

View File

@ -4,7 +4,7 @@
#include "spdlog/spdlog.h"
#include "src/cpp/core/YogaWidget/yogawidget.h"
FlexLayout::NodeContext *FlexLayout::getNodeContext(YGNodeRef node)
FlexLayout::NodeContext* FlexLayout::getNodeContext(YGNodeRef node)
{
if(!node){
return nullptr;
@ -16,7 +16,6 @@ FlexLayout::NodeContext *FlexLayout::getNodeContext(YGNodeRef node)
FlexLayout::FlexLayout(QWidget *parentWidget, YGNodeRef parentNode): QLayout(parentWidget)
{
// spdlog::set_level(spdlog::level::off);
this->node = parentNode;
}
@ -58,7 +57,6 @@ QLayoutItem *FlexLayout::itemAt(int index) const
YGNodeRef childNode = YGNodeGetChild(this->node, static_cast<uint>(index));
NodeContext *ctx = getNodeContext(childNode);
if(!ctx){
// spdlog::info("flexlayout: itemAt null context {}",index);
return nullptr;
}
return ctx->item;
@ -91,14 +89,13 @@ void FlexLayout::addWidget(QWidget* childWidget, YGNodeRef childNode)
spdlog::warn("Flex layout's parent yoga node not set yet. Set it using setFlexNode. Child widget will not be added to Flex Layout");
return;
}
// spdlog::info("flexlayout: addWidget Object: {}",childWidget->metaObject()->className());
uint count = YGNodeGetChildCount(this->node);
YGNodeInsertChild(this->node,childNode, count);
QLayoutItem* layoutItem = new QWidgetItem(childWidget);
NodeContext* childContext = new NodeContext(layoutItem);
YGNodeSetContext(childNode, static_cast<void *>(childContext));
QLayout::addWidget(childWidget);
this->invalidate();
}
void FlexLayout::removeWidget(QWidget* childWidget, YGNodeRef childNode)
@ -114,6 +111,7 @@ void FlexLayout::removeWidget(QWidget* childWidget, YGNodeRef childNode)
}
YGNodeRemoveChild(this->node, childNode);
QLayout::removeWidget(childWidget);
this->invalidate();
}
void FlexLayout::insertChildBefore(QWidget* childWidget, YGNodeRef beforeChildNode, YGNodeRef childNode)
@ -135,14 +133,30 @@ void FlexLayout::insertChildBefore(QWidget* childWidget, YGNodeRef beforeChildNo
NodeContext* childContext = new NodeContext(layoutItem);
YGNodeSetContext(childNode, static_cast<void *>(childContext));
QLayout::addWidget(childWidget);
this->invalidate();
}
YGNodeRef FlexLayout::getRootNode(YGNodeRef node){
YGNodeRef parent = node->getOwner();
if(!parent){
return node;
}else {
return getRootNode(parent);
}
}
void FlexLayout::setGeometry(const QRect &rect)
{
if(!this->node){
return;
}
YGNodeRef rootNode = getRootNode(this->node);
QWidget* parentWidget = this->parentWidget();
QWidget* window = parentWidget->window();
YGDirection direction = YGNodeStyleGetDirection(rootNode);
YGNodeCalculateLayout(rootNode,window->width(),window->height(),direction);
uint count = YGNodeGetChildCount(this->node);
for (uint i = 0; i < count; ++i) {

View File

@ -24,6 +24,7 @@ class FlexLayout: public QLayout
{
private:
YGNodeRef node;
YGNodeRef getRootNode(YGNodeRef node);
public:
struct NodeContext
{

View File

@ -1,4 +1,5 @@
#include "src/cpp/QtGui/QApplication/qapplication_wrap.h"
#include "src/cpp/QtGui/QClipboard/qclipboard_wrap.h"
#include "src/cpp/QtWidgets/QWidget/qwidget_wrap.h"
#include "src/cpp/QtGui/QPixmap/qpixmap_wrap.h"
#include "src/cpp/QtGui/QIcon/qicon_wrap.h"
@ -28,6 +29,7 @@ void InitPrivateHelpers(Napi::Env env){
Napi::Object Main(Napi::Env env, Napi::Object exports) {
InitPrivateHelpers(env);
QApplicationWrap::init(env, exports);
QClipboardWrap::init(env, exports);
QWidgetWrap::init(env, exports);
QPixmapWrap::init(env, exports);
QIconWrap::init(env, exports);

View File

@ -12,11 +12,17 @@ import {
QDial,
QPlainTextEdit,
QTabWidget,
QGridLayout
QGridLayout,
QScrollArea,
QPixmap,
CursorShape,
WindowState,
QTextOptionWrapMode,
QApplication,
QClipboardMode,
QCheckBoxEvents
} from "./index";
import { QScrollArea } from "./lib/QtWidgets/QScrollArea";
import { QPixmap } from "./lib/QtGui/QPixmap";
import { CursorShape, WindowState } from "./lib/QtEnums"
import { QTabWidgetEvents } from "./lib/QtWidgets/QTabWidget";
const path = require("path");
@ -37,6 +43,9 @@ const checkbox = new QCheckBox();
checkbox.setText("Check me out?");
checkbox.setObjectName("check");
checkbox.setChecked(true);
checkbox.addEventListener(QCheckBoxEvents.toggled, () => {
console.log('checkbox was toggled!');
})
const dial = new QDial();
checkbox.setObjectName("dial");
@ -49,6 +58,15 @@ const button = new QPushButton();
button.setText("Push Push Push!");
button.setObjectName("btn");
button.setFlat(true);
button.addEventListener("clicked", () => {
const clipboard = QApplication.clipboard();
console.log("clipboard: ", clipboard.text(QClipboardMode.Clipboard));
clipboard.setText("yooooo", QClipboardMode.Clipboard);
if (rootView.layout) {
(rootView.layout as FlexLayout).removeWidget(dial);
}
label.setInlineStyle("color:blue;");
});
const nodeguiLogo = new QIcon(
path.resolve(__dirname, "../extras/assets/nodegui.png")
@ -88,6 +106,7 @@ rootView.setLayout(new FlexLayout());
const textEdit = new QPlainTextEdit();
textEdit.setPlainText("Hello");
textEdit.setWordWrapMode(QTextOptionWrapMode.NoWrap);
const scrollArea = new QScrollArea();
scrollArea.setInlineStyle("flex: 1; width:'100%';");
@ -123,8 +142,7 @@ win.setStyleSheet(`
win.setWindowIcon(nodeguiLogo);
win.setWindowTitle("NodeGUI Demo");
win.resize(400, 500);
win.resize(400, 700);
win.show();
win.setWindowState(WindowState.WindowActive);

View File

@ -1,10 +1,14 @@
// bootstrap
import "./lib/core/bootstrap";
// Enums:
export * from "./lib/QtEnums";
// Gui:
export { QApplication } from "./lib/QtGui/QApplication";
export { QPixmap } from "./lib/QtGui/QPixmap";
export { QIcon } from "./lib/QtGui/QIcon";
export { QIcon, QIconMode, QIconState } from "./lib/QtGui/QIcon";
export { QCursor } from "./lib/QtGui/QCursor";
export { QTextOptionWrapMode } from "./lib/QtGui/QTextOption";
export { QClipboard, QClipboardMode } from "./lib/QtGui/QClipboard";
// Events: Maybe a separate module ?
export { QKeyEvent } from "./lib/QtGui/QEvent/QKeyEvent";
export { NativeEvent } from "./lib/core/EventWidget";
@ -27,7 +31,8 @@ export { QRadioButton, QRadioButtonEvents } from "./lib/QtWidgets/QRadioButton";
export { QTabWidget, QTabWidgetEvents } from "./lib/QtWidgets/QTabWidget";
export {
QPlainTextEdit,
QPlainTextEditEvents
QPlainTextEditEvents,
LineWrapMode
} from "./lib/QtWidgets/QPlainTextEdit";
export { QScrollArea, QScrollAreaEvents } from "./lib/QtWidgets/QScrollArea";
// Layouts:

View File

@ -1,6 +1,7 @@
import addon from "../../core/addon";
import { Component, NativeElement } from "../../core/Component";
import { checkIfNativeElement } from "../../utils";
import { QClipboard } from "../QClipboard";
type arg = NativeElement;
export class QApplication extends Component {
@ -13,6 +14,9 @@ export class QApplication extends Component {
this.native = new addon.QApplication();
}
}
static clipboard = (): QClipboard => {
return new QClipboard(addon.QApplication.clipboard());
};
processEvents = () => {
this.native.processEvents();
};

View File

@ -0,0 +1,31 @@
import { Component, NativeElement } from "../../core/Component";
import { checkIfNativeElement } from "../../utils";
export class QClipboard extends Component {
native: NativeElement;
constructor(native: NativeElement) {
super();
if (checkIfNativeElement(native)) {
this.native = native;
} else {
throw new Error(
"QClipboard cannot be initialised this way. Use QApplication::clipboard()"
);
}
}
clear = (mode: QClipboardMode) => {
this.native.clear(mode);
};
setText = (text: string, mode: QClipboardMode) => {
this.native.setText(text, mode);
};
text = (mode: QClipboardMode): string => {
return this.native.text(mode);
};
}
export enum QClipboardMode {
Clipboard,
Selection,
FindBuffer
}

View File

@ -1,5 +1,17 @@
import addon from "../../core/addon";
import { Component, NativeElement } from "../../core/Component";
import { QPixmap } from "../../QtGui/QPixmap";
export enum QIconMode {
Normal,
Disabled,
Active,
Selected
}
export enum QIconState {
Off,
On
}
type arg = string | NativeElement;
export class QIcon extends Component {
@ -13,4 +25,20 @@ export class QIcon extends Component {
this.native = new addon.QIcon();
}
}
pixmap = (
width: number,
height: number,
mode?: QIconMode,
state?: QIconState
): QPixmap => {
let nativePixmap;
if (mode && state) {
nativePixmap = this.native.pixmap(width, height, mode, state);
} else if (mode) {
nativePixmap = this.native.pixmap(width, height, mode);
} else {
nativePixmap = this.native.pixmap(width, height);
}
return new QPixmap(nativePixmap);
};
}

View File

@ -0,0 +1,7 @@
export enum QTextOptionWrapMode {
NoWrap,
WordWrap,
ManualWrap,
WrapAnywhere,
WrapAtWordBoundaryOrAnywhere
}

View File

@ -4,7 +4,8 @@ import { BaseWidgetEvents } from "../../core/EventWidget";
import { NativeElement } from "../../core/Component";
export const QCheckBoxEvents = Object.freeze({
...BaseWidgetEvents
...BaseWidgetEvents,
toggled: "toggled"
});
export class QCheckBox extends NodeWidget {
native: NativeElement;

View File

@ -32,6 +32,7 @@ export class QMainWindow extends NodeWidget {
};
}
setCentralWidget(widget: NodeWidget) {
// react:✓
this.native.setCentralWidget(widget.native, widget.getFlexNode());
this.centralWidget = widget;
}

View File

@ -3,14 +3,27 @@ import { NodeWidget } from "../QWidget";
import { BaseWidgetEvents } from "../../core/EventWidget";
import { NativeElement } from "../../core/Component";
import { QAbstractScrollArea } from "../QAbstractScrollArea";
import { QTextOptionWrapMode } from "../../QtGui/QTextOption";
export const QPlainTextEditEvents = Object.freeze({
...BaseWidgetEvents,
textChanged: "textChanged"
textChanged: "textChanged",
blockCountChanged: "blockCountChanged",
copyAvailable: "copyAvailable",
cursorPositionChanged: "cursorPositionChanged",
modificationChanged: "modificationChanged",
redoAvailable: "redoAvailable",
selectionChanged: "selectionChanged",
undoAvailable: "undoAvailable"
});
export enum LineWrapMode {
NoWrap,
WidgetWidth
}
export class QPlainTextEdit extends QAbstractScrollArea {
native: NativeElement;
placeholderText?: string;
constructor(parent?: NodeWidget) {
let native;
if (parent) {
@ -23,15 +36,25 @@ export class QPlainTextEdit extends QAbstractScrollArea {
this.parent = parent;
// bind member functions
this.setPlainText.bind(this);
this.setPlaceholderText.bind(this);
this.toPlainText.bind(this);
this.setReadOnly.bind(this);
this.clear.bind(this);
this.setWordWrapMode.bind(this);
this.wordWrapMode.bind(this);
this.setLineWrapMode.bind(this);
this.lineWrapMode.bind(this);
}
setPlainText(text: string | number) {
// react:✓
this.native.setPlainText(`${text}`);
}
toPlainText() {
setPlaceholderText(text: string) {
// react:✓, //TODO:getter
this.placeholderText = text;
this.native.setPlaceholderText(text);
}
toPlainText(): string {
// react:✓
return this.native.toPlainText();
}
@ -43,4 +66,16 @@ export class QPlainTextEdit extends QAbstractScrollArea {
// react:✓
this.native.clear();
}
setWordWrapMode(mode: QTextOptionWrapMode) {
this.native.setWordWrapMode(mode);
}
wordWrapMode(): QTextOptionWrapMode {
return this.native.wordWrapMode();
}
setLineWrapMode(mode: LineWrapMode) {
this.native.setLineWrapMode(mode);
}
lineWrapMode(): LineWrapMode {
return this.native.lineWrapMode();
}
}

View File

@ -28,16 +28,16 @@ export class QPushButton extends NodeWidget {
this.setText.bind(this);
this.setFlat.bind(this);
}
setText(text: string | number) {
// react:✓, //TODO:getter
this.native.setText(`${text}`);
}
setFlat(isFlat: boolean) {
// react:✓, //TODO:getter
this.native.setFlat(isFlat);
}
setIcon(icon: QIcon) {
// react:✓, //TODO:getter
this.native.setIcon(icon.native);
}
}

View File

@ -9,7 +9,7 @@ export const QScrollAreaEvents = Object.freeze({
});
export class QScrollArea extends QAbstractScrollArea {
native: NativeElement;
contentWidget?: NodeWidget;
contentWidget?: NodeWidget | null;
constructor(parent?: NodeWidget) {
let native;
if (parent) {
@ -21,9 +21,22 @@ export class QScrollArea extends QAbstractScrollArea {
this.native = native;
this.parent = parent;
// bind member functions
this.setWidget.bind(this);
this.takeWidget.bind(this);
}
setWidget(widget: NodeWidget) {
// react:✓, //TODO:getter
this.contentWidget = widget;
this.native.setWidget(widget.native);
}
takeWidget(): NodeWidget | null {
// react:✓
const contentWidget = this.contentWidget;
this.contentWidget = null;
if (contentWidget) {
this.native.takeWidget();
return contentWidget;
}
return null;
}
}

View File

@ -45,9 +45,13 @@ export abstract class NodeWidget extends EventWidget {
await applyStyleSheet(this, preparedSheet);
};
setGeometry = (x: number, y: number, w: number, h: number) => {
// react:✓, //TODO:getter
// react:✓
this.native.setGeometry(x, y, w, h);
};
geometry = (): Rect => {
// react:✓
return this.native.geometry();
};
setObjectName = (objectName: string) => {
// react:✓
this.native.setObjectName(objectName);
@ -148,6 +152,12 @@ export abstract class NodeWidget extends EventWidget {
};
}
type Rect = {
x: number;
y: number;
width: number;
height: number;
};
type arg = NodeWidget | NativeElement;
export class QWidget extends NodeWidget {

View File

@ -19,7 +19,7 @@ export const prepareInlineStyleSheet = async (
rawStyle: string
) => {
const inlineStyle = await StyleSheet.create(rawStyle);
// Make sure to not calculate ObjectName is the same pass of event loop as other props (incase of react) since the order will matter in that case
// Make sure to not calculate ObjectName in the same pass of event loop as other props (incase of react) since the order will matter in that case
// So doing it in multiple passes of event loop allows objectName to be set before using it. The above await solves it.
let cssId = widget.objectName();
if (!cssId) {
@ -38,7 +38,5 @@ export const applyStyleSheet = async (
styleSheet: string
) => {
widget.native.setStyleSheet(styleSheet);
setTimeout(() => {
widget.layout ? widget.layout.update() : widget.update();
}, 20);
widget.layout ? widget.layout.update() : widget.update();
};

26
src/lib/core/bootstrap.ts Normal file
View File

@ -0,0 +1,26 @@
/*
From: https://github.com/yue/yode/blob/master/src/bootstrap.js
setImmediate and process.nextTick makes use of uv_check and uv_prepare to
run the callbacks, however since we only run uv loop on requests, the
callbacks wouldn't be called until something else activated the uv loop,
which would delay the callbacks for arbitrary long time. So we should
initiatively activate the uv loop once setImmediate and process.nextTick is
called.
This is required inorder to make the timers work nicely due to merger of event loops
*/
function wrapWithActivateUvLoop(func: any) {
return function() {
(process as any).activateUvLoop();
//@ts-ignore
return func.apply(this, arguments);
};
}
const main = () => {
process.nextTick = wrapWithActivateUvLoop(process.nextTick);
global.setImmediate = wrapWithActivateUvLoop(global.setImmediate);
global.setTimeout = wrapWithActivateUvLoop(global.setTimeout);
global.setInterval = wrapWithActivateUvLoop(global.setInterval);
};
main();