Add qvariant object translation (#189)
* working - translation of any wrapped object * clang format * Adds QVariant and Qbject property. Also adds QPixmap fromQVariant * fixes breaking test cases * Adds build to prepush hook aswell
This commit is contained in:
parent
88cd9d430f
commit
ece01d3803
@ -43,6 +43,7 @@ add_library(${CORE_WIDGETS_ADDON} SHARED
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QCursor/qcursor_wrap.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QKeySequence/qkeysequence_wrap.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/lib/QtCore/QVariant/qvariant_wrap.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QGridLayout/qgridlayout_wrap.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QDial/qdial_wrap.cpp"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const { QApplication } = require("../../dist");
|
||||
const { QApplication } = require('../../dist');
|
||||
module.exports = async () => {
|
||||
global.qApp = QApplication.instance();
|
||||
qApp.setQuitOnLastWindowClosed(false);
|
||||
global.qApp = QApplication.instance();
|
||||
qApp.setQuitOnLastWindowClosed(false);
|
||||
};
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
module.exports = async () => {
|
||||
global.qApp.quit();
|
||||
global.qApp.quit();
|
||||
};
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
// For a detailed explanation regarding each configuration property, visit:
|
||||
// https://jestjs.io/docs/en/configuration.html
|
||||
module.exports = {
|
||||
clearMocks: true,
|
||||
coverageDirectory: "coverage",
|
||||
collectCoverageFrom: ["**/*.{js,jsx,ts,tsx}", "!**/node_modules/**"],
|
||||
forceCoverageMatch: ["**/*.{ts,tsx,js,jsx}", "!**/*.test.{ts,tsx,js,jsx}"],
|
||||
moduleFileExtensions: ["js", "json", "jsx", "ts", "tsx", "node"],
|
||||
roots: ["<rootDir>/src/lib"],
|
||||
testEnvironment: "node",
|
||||
transform: {
|
||||
"^.+\\.tsx?$": "ts-jest"
|
||||
},
|
||||
globalSetup: "./config/tests/setup.js",
|
||||
globalTeardown: "./config/tests/teardown.js"
|
||||
clearMocks: true,
|
||||
coverageDirectory: 'coverage',
|
||||
collectCoverageFrom: ['**/*.{js,jsx,ts,tsx}', '!**/node_modules/**'],
|
||||
forceCoverageMatch: ['**/*.{ts,tsx,js,jsx}', '!**/*.test.{ts,tsx,js,jsx}'],
|
||||
moduleFileExtensions: ['js', 'json', 'jsx', 'ts', 'tsx', 'node'],
|
||||
roots: ['<rootDir>/src/lib'],
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\.tsx?$': 'ts-jest',
|
||||
},
|
||||
globalSetup: './config/tests/setup.js',
|
||||
globalTeardown: './config/tests/teardown.js',
|
||||
};
|
||||
|
||||
@ -19,8 +19,8 @@
|
||||
"dev": "npm run build && qode --inspect dist/demo.js",
|
||||
"postinstall": "npm run build:addon",
|
||||
"build": "tsc && npm run build:addon",
|
||||
"build:addon": "cross-env CMAKE_BUILD_PARALLEL_LEVEL=8 cmake-js build",
|
||||
"test": "qode ./node_modules/.bin/jest",
|
||||
"build:addon": "cross-env CMAKE_BUILD_PARALLEL_LEVEL=8 cmake-js compile",
|
||||
"test": "qode ./node_modules/.bin/jest -i",
|
||||
"lint:cpp": "clang-format -i --glob=src/cpp/**/*.[h,c]*",
|
||||
"lint:ts": "tsc --noEmit && eslint './src/**/*.{ts,tsx,js,jsx}' --fix"
|
||||
},
|
||||
@ -50,7 +50,7 @@
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-push": "npm run lint:ts && npm run lint:cpp && npm run test"
|
||||
"pre-push": "npm run build && npm run lint:ts && npm run lint:cpp && npm run test"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Extras/Utils/nutils.h"
|
||||
#include "QtCore/QVariant/qvariant_wrap.h"
|
||||
#include "core/Events/eventwidget_macro.h"
|
||||
/*
|
||||
|
||||
@ -31,6 +32,17 @@
|
||||
this->instance->setProperty(name.Utf8Value().c_str(), *variant); \
|
||||
return env.Null(); \
|
||||
} \
|
||||
Napi::Value property(const Napi::CallbackInfo& info) { \
|
||||
Napi::Env env = info.Env(); \
|
||||
Napi::HandleScope scope(env); \
|
||||
Napi::String name = info[0].As<Napi::String>(); \
|
||||
Napi::Value value = info[1]; \
|
||||
QVariant* variant = \
|
||||
new QVariant(this->instance->property(name.Utf8Value().c_str())); \
|
||||
auto variantWrap = QVariantWrap::constructor.New( \
|
||||
{Napi::External<QVariant>::New(env, variant)}); \
|
||||
return variantWrap; \
|
||||
} \
|
||||
Napi::Value setObjectName(const Napi::CallbackInfo& info) { \
|
||||
Napi::Env env = info.Env(); \
|
||||
Napi::HandleScope scope(env); \
|
||||
@ -55,6 +67,7 @@
|
||||
\
|
||||
InstanceMethod("inherits", &ComponentWrapName::inherits), \
|
||||
InstanceMethod("setProperty", &ComponentWrapName::setProperty), \
|
||||
InstanceMethod("property", &ComponentWrapName::property), \
|
||||
InstanceMethod("setObjectName", &ComponentWrapName::setObjectName), \
|
||||
InstanceMethod("objectName", &ComponentWrapName::objectName),
|
||||
|
||||
|
||||
25
src/cpp/include/nodegui/QtCore/QVariant/qvariant_wrap.h
Normal file
25
src/cpp/include/nodegui/QtCore/QVariant/qvariant_wrap.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include "core/Component/component_macro.h"
|
||||
|
||||
class QVariantWrap : public Napi::ObjectWrap<QVariantWrap> {
|
||||
private:
|
||||
QSharedPointer<QVariant> instance;
|
||||
|
||||
public:
|
||||
static Napi::Object init(Napi::Env env, Napi::Object exports);
|
||||
QVariantWrap(const Napi::CallbackInfo& info);
|
||||
QVariant* getInternalInstance();
|
||||
// class constructor
|
||||
static Napi::FunctionReference constructor;
|
||||
Napi::Value toString(const Napi::CallbackInfo& info);
|
||||
Napi::Value toInt(const Napi::CallbackInfo& info);
|
||||
Napi::Value toDouble(const Napi::CallbackInfo& info);
|
||||
Napi::Value toBool(const Napi::CallbackInfo& info);
|
||||
// wrapped methods
|
||||
COMPONENT_WRAPPED_METHODS_DECLARATION
|
||||
};
|
||||
@ -21,6 +21,12 @@ class QPixmapWrap : public Napi::ObjectWrap<QPixmapWrap> {
|
||||
Napi::Value load(const Napi::CallbackInfo& info);
|
||||
Napi::Value save(const Napi::CallbackInfo& info);
|
||||
Napi::Value scaled(const Napi::CallbackInfo& info);
|
||||
Napi::Value height(const Napi::CallbackInfo& info);
|
||||
Napi::Value width(const Napi::CallbackInfo& info);
|
||||
|
||||
COMPONENT_WRAPPED_METHODS_DECLARATION
|
||||
};
|
||||
|
||||
namespace StaticQPixmapWrapMethods {
|
||||
Napi::Value fromQVariant(const Napi::CallbackInfo& info);
|
||||
} // namespace StaticQPixmapWrapMethods
|
||||
@ -1,6 +1,5 @@
|
||||
#include "Extras/Utils/nutils.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMetaType>
|
||||
#include <QWidget>
|
||||
#include <string>
|
||||
@ -91,8 +90,8 @@ QVariant* extrautils::convertToQVariant(Napi::Env& env, Napi::Value& value) {
|
||||
// TODO: fix this
|
||||
return new QVariant();
|
||||
} else if (value.IsExternal()) {
|
||||
// TODO: fix this
|
||||
return new QVariant();
|
||||
QVariant* variant = value.As<Napi::External<QVariant>>().Data();
|
||||
return variant;
|
||||
} else {
|
||||
return new QVariant();
|
||||
}
|
||||
|
||||
61
src/cpp/lib/QtCore/QVariant/qvariant_wrap.cpp
Normal file
61
src/cpp/lib/QtCore/QVariant/qvariant_wrap.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "QtCore/QVariant/qvariant_wrap.h"
|
||||
|
||||
#include "Extras/Utils/nutils.h"
|
||||
|
||||
Napi::FunctionReference QVariantWrap::constructor;
|
||||
|
||||
Napi::Object QVariantWrap::init(Napi::Env env, Napi::Object exports) {
|
||||
Napi::HandleScope scope(env);
|
||||
char CLASSNAME[] = "QVariant";
|
||||
Napi::Function func =
|
||||
DefineClass(env, CLASSNAME,
|
||||
{InstanceMethod("toString", &QVariantWrap::toString),
|
||||
InstanceMethod("toInt", &QVariantWrap::toInt),
|
||||
InstanceMethod("toDouble", &QVariantWrap::toDouble),
|
||||
InstanceMethod("toBool", &QVariantWrap::toBool),
|
||||
COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE});
|
||||
constructor = Napi::Persistent(func);
|
||||
exports.Set(CLASSNAME, func);
|
||||
return exports;
|
||||
}
|
||||
|
||||
QVariant* QVariantWrap::getInternalInstance() { return this->instance.data(); }
|
||||
|
||||
QVariantWrap::QVariantWrap(const Napi::CallbackInfo& info)
|
||||
: Napi::ObjectWrap<QVariantWrap>(info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
if (info.Length() == 1) {
|
||||
Napi::Value value = info[0].As<Napi::Value>();
|
||||
this->instance =
|
||||
QSharedPointer<QVariant>(extrautils::convertToQVariant(env, value));
|
||||
} else {
|
||||
this->instance = QSharedPointer<QVariant>(new QVariant());
|
||||
}
|
||||
this->rawData = this->getInternalInstance();
|
||||
}
|
||||
|
||||
Napi::Value QVariantWrap::toString(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
QString value = this->instance->value<QString>();
|
||||
return Napi::Value::From(env, value.toStdString());
|
||||
}
|
||||
Napi::Value QVariantWrap::toInt(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
int value = this->instance->value<int>();
|
||||
return Napi::Value::From(env, value);
|
||||
}
|
||||
Napi::Value QVariantWrap::toDouble(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
double value = this->instance->value<double>();
|
||||
return Napi::Value::From(env, value);
|
||||
}
|
||||
Napi::Value QVariantWrap::toBool(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
bool value = this->instance->value<bool>();
|
||||
return Napi::Value::From(env, value);
|
||||
}
|
||||
@ -1,19 +1,22 @@
|
||||
#include "QtGui/QPixmap/qpixmap_wrap.h"
|
||||
|
||||
#include "Extras/Utils/nutils.h"
|
||||
#include "deps/spdlog/spdlog.h"
|
||||
#include "QtCore/QVariant/qvariant_wrap.h"
|
||||
|
||||
Napi::FunctionReference QPixmapWrap::constructor;
|
||||
|
||||
Napi::Object QPixmapWrap::init(Napi::Env env, Napi::Object exports) {
|
||||
Napi::HandleScope scope(env);
|
||||
char CLASSNAME[] = "QPixmap";
|
||||
Napi::Function func =
|
||||
DefineClass(env, CLASSNAME,
|
||||
{InstanceMethod("load", &QPixmapWrap::load),
|
||||
InstanceMethod("save", &QPixmapWrap::save),
|
||||
InstanceMethod("scaled", &QPixmapWrap::scaled),
|
||||
COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE});
|
||||
Napi::Function func = DefineClass(
|
||||
env, CLASSNAME,
|
||||
{InstanceMethod("load", &QPixmapWrap::load),
|
||||
InstanceMethod("save", &QPixmapWrap::save),
|
||||
InstanceMethod("scaled", &QPixmapWrap::scaled),
|
||||
InstanceMethod("height", &QPixmapWrap::height),
|
||||
InstanceMethod("width", &QPixmapWrap::width),
|
||||
StaticMethod("fromQVariant", &StaticQPixmapWrapMethods::fromQVariant),
|
||||
COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE});
|
||||
constructor = Napi::Persistent(func);
|
||||
exports.Set(CLASSNAME, func);
|
||||
return exports;
|
||||
@ -98,3 +101,28 @@ Napi::Value QPixmapWrap::scaled(const Napi::CallbackInfo& info) {
|
||||
{Napi::External<QPixmap>::New(env, updatedPixMap)});
|
||||
return instance;
|
||||
}
|
||||
|
||||
Napi::Value QPixmapWrap::height(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
return Napi::Value::From(env, this->instance->height());
|
||||
}
|
||||
Napi::Value QPixmapWrap::width(const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
return Napi::Value::From(env, this->instance->width());
|
||||
}
|
||||
|
||||
Napi::Value StaticQPixmapWrapMethods::fromQVariant(
|
||||
const Napi::CallbackInfo& info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::HandleScope scope(env);
|
||||
Napi::Object variantObject = info[0].As<Napi::Object>();
|
||||
QVariantWrap* variantWrap =
|
||||
Napi::ObjectWrap<QVariantWrap>::Unwrap(variantObject);
|
||||
QVariant* variant = variantWrap->getInternalInstance();
|
||||
QPixmap pixmap = variant->value<QPixmap>();
|
||||
auto instance = QPixmapWrap::constructor.New(
|
||||
{Napi::External<QPixmap>::New(env, new QPixmap(pixmap))});
|
||||
return instance;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include <napi.h>
|
||||
|
||||
#include "QtCore/QObject/qobject_wrap.h"
|
||||
#include "QtCore/QVariant/qvariant_wrap.h"
|
||||
#include "QtGui/QApplication/qapplication_wrap.h"
|
||||
#include "QtGui/QClipboard/qclipboard_wrap.h"
|
||||
#include "QtGui/QCursor/qcursor_wrap.h"
|
||||
@ -38,6 +39,7 @@ Napi::Object Main(Napi::Env env, Napi::Object exports) {
|
||||
InitPrivateHelpers(env);
|
||||
QApplicationWrap::init(env, exports);
|
||||
QObjectWrap::init(env, exports);
|
||||
QVariantWrap::init(env, exports);
|
||||
QClipboardWrap::init(env, exports);
|
||||
QWidgetWrap::init(env, exports);
|
||||
QPixmapWrap::init(env, exports);
|
||||
|
||||
@ -39,6 +39,7 @@ export { QAction, QActionEvents } from './lib/QtWidgets/QAction';
|
||||
export { QShortcut, QShortcutEvents } from './lib/QtWidgets/QShortcut';
|
||||
// Core
|
||||
export { QObject, NodeObject } from './lib/QtCore/QObject';
|
||||
export { QVariant } from './lib/QtCore/QVariant';
|
||||
// Layouts:
|
||||
export { QGridLayout } from './lib/QtWidgets/QGridLayout';
|
||||
export { FlexLayout } from './lib/core/FlexLayout';
|
||||
|
||||
@ -2,6 +2,7 @@ import { EventWidget } from '../core/EventWidget';
|
||||
import { NativeElement } from '../core/Component';
|
||||
import { checkIfNativeElement } from '../utils/helpers';
|
||||
import addon from '../utils/addon';
|
||||
import { QVariant } from './QVariant';
|
||||
|
||||
export abstract class NodeObject extends EventWidget {
|
||||
inherits(className: string): boolean {
|
||||
@ -11,6 +12,10 @@ export abstract class NodeObject extends EventWidget {
|
||||
const finalValue = value.native || value;
|
||||
return this.native.setProperty(name, finalValue);
|
||||
}
|
||||
property(name: string): QVariant {
|
||||
const nativeVariant = this.native.property(name);
|
||||
return new QVariant(nativeVariant);
|
||||
}
|
||||
setObjectName(objectName: string): void {
|
||||
this.native.setObjectName(objectName);
|
||||
}
|
||||
|
||||
32
src/lib/QtCore/QVariant.ts
Normal file
32
src/lib/QtCore/QVariant.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { NativeElement, Component } from '../core/Component';
|
||||
import addon from '../utils/addon';
|
||||
import { checkIfNativeElement } from '../utils/helpers';
|
||||
|
||||
type QVariantType = NativeElement | Component | string | number | boolean;
|
||||
|
||||
export class QVariant extends Component {
|
||||
native: NativeElement;
|
||||
constructor(arg?: QVariantType) {
|
||||
super();
|
||||
if (checkIfNativeElement(arg)) {
|
||||
this.native = arg as NativeElement;
|
||||
} else if (arg) {
|
||||
const component = (arg as Component).native || arg;
|
||||
this.native = new addon.QVariant(component);
|
||||
} else {
|
||||
this.native = new addon.QVariant();
|
||||
}
|
||||
}
|
||||
toString(): string {
|
||||
return this.native.toString();
|
||||
}
|
||||
toInt(): string {
|
||||
return this.native.toInt();
|
||||
}
|
||||
toDouble(): string {
|
||||
return this.native.toDouble();
|
||||
}
|
||||
toBool(): string {
|
||||
return this.native.toBool();
|
||||
}
|
||||
}
|
||||
@ -9,4 +9,9 @@ describe('QObject', () => {
|
||||
component.setObjectName('hello');
|
||||
expect(component.objectName()).toEqual('hello');
|
||||
});
|
||||
it('setProperty', () => {
|
||||
component.setProperty('objectName', 'testObjName');
|
||||
const variant = component.property('objectName');
|
||||
expect(variant.toString()).toEqual('testObjName');
|
||||
});
|
||||
});
|
||||
|
||||
40
src/lib/QtCore/__tests__/QVariant.test.ts
Normal file
40
src/lib/QtCore/__tests__/QVariant.test.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { QVariant } from '../../../index';
|
||||
import { QPixmap } from '../../QtGui/QPixmap';
|
||||
import path from 'path';
|
||||
|
||||
describe('QVariant', () => {
|
||||
it('inherits from QVariant', () => {
|
||||
const variant = new QVariant();
|
||||
expect(variant.constructor.name).toEqual('QVariant');
|
||||
});
|
||||
it('initialize empty', () => {
|
||||
const variant = new QVariant();
|
||||
expect(variant.constructor.name).toEqual('QVariant');
|
||||
});
|
||||
it('initialize with string', () => {
|
||||
const variant = new QVariant('hello');
|
||||
expect(variant.constructor.name).toBe('QVariant');
|
||||
expect(variant.toString()).toEqual('hello');
|
||||
});
|
||||
it('initialize with int', () => {
|
||||
const variant = new QVariant(123);
|
||||
expect(variant.constructor.name).toBe('QVariant');
|
||||
expect(variant.toInt()).toEqual(123);
|
||||
});
|
||||
it('initialize with double', () => {
|
||||
const variant = new QVariant(12.33);
|
||||
expect(variant.constructor.name).toBe('QVariant');
|
||||
expect(variant.toDouble()).toEqual(12.33);
|
||||
});
|
||||
it('initialize with boolean', () => {
|
||||
const variant = new QVariant(true);
|
||||
expect(variant.constructor.name).toBe('QVariant');
|
||||
expect(variant.toBool()).toEqual(true);
|
||||
});
|
||||
it('initialize with complex objects', () => {
|
||||
const pixmap = new QPixmap(path.resolve(__dirname, 'nodegui.png'));
|
||||
const variant = new QVariant(pixmap);
|
||||
expect(variant.constructor.name).toBe('QVariant');
|
||||
expect(QPixmap.fromQVariant(variant).height()).toBe(pixmap.height());
|
||||
});
|
||||
});
|
||||
BIN
src/lib/QtCore/__tests__/nodegui.png
Normal file
BIN
src/lib/QtCore/__tests__/nodegui.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
@ -2,6 +2,7 @@ import addon from '../utils/addon';
|
||||
import { Component, NativeElement } from '../core/Component';
|
||||
import { AspectRatioMode } from '../QtEnums';
|
||||
import { checkIfNativeElement } from '../utils/helpers';
|
||||
import { QVariant } from '../QtCore/QVariant';
|
||||
|
||||
export type ImageFormats = 'BMP' | 'GIF' | 'JPG' | 'JPEG' | 'PNG' | 'PBM' | 'PGM' | 'PPM' | 'XBM' | 'XPM';
|
||||
export type ReadWriteImageFormats = 'BMP' | 'JPG' | 'JPEG' | 'PNG' | 'PBM' | 'XBM' | 'XPM';
|
||||
@ -36,4 +37,13 @@ export class QPixmap extends Component {
|
||||
}
|
||||
return new QPixmap(nativePixmap);
|
||||
};
|
||||
height(): number {
|
||||
return this.native.height();
|
||||
}
|
||||
width(): number {
|
||||
return this.native.width();
|
||||
}
|
||||
static fromQVariant(variant: QVariant): QPixmap {
|
||||
return addon.QPixmap.fromQVariant(variant.native);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,8 +7,8 @@ export enum EchoMode {
|
||||
Normal,
|
||||
NoEcho,
|
||||
Password,
|
||||
PasswordEchoOnEdit,
|
||||
};
|
||||
PasswordEchoOnEdit,
|
||||
}
|
||||
export const QLineEditEvents = Object.freeze({
|
||||
...BaseWidgetEvents,
|
||||
cursorPositionChanged: 'cursorPositionChanged',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user