From 6bc7f1274694170a9ad5247b760ce8d48e9cee09 Mon Sep 17 00:00:00 2001 From: mspencer92 Date: Wed, 25 Mar 2020 17:06:53 -0400 Subject: [PATCH] Added QStandardModel (#467) * Added QStandardModel * Update demo.ts --- CMakeLists.txt | 4 +- .../QtWidgets/QComboBox/qcombobox_wrap.h | 2 + .../QStandardItem/qstandarditem_wrap.h | 34 +++++++ .../QStandardItemModel/nstandarditemmodel.hpp | 31 +++++++ .../qstandarditemmodel_wrap.h | 25 +++++ .../QtWidgets/QComboBox/qcombobox_wrap.cpp | 26 ++++++ .../QStandardItem/qstandarditem_wrap.cpp | 91 +++++++++++++++++++ .../qstandarditemmodel_wrap.cpp | 70 ++++++++++++++ src/cpp/main.cpp | 4 + src/index.ts | 1 + src/lib/QtWidgets/QComboBox.ts | 7 ++ src/lib/QtWidgets/QStandardItem.ts | 36 ++++++++ src/lib/QtWidgets/QStandardItemModel.ts | 34 +++++++ 13 files changed, 364 insertions(+), 1 deletion(-) create mode 100644 src/cpp/include/nodegui/QtWidgets/QStandardItem/qstandarditem_wrap.h create mode 100644 src/cpp/include/nodegui/QtWidgets/QStandardItemModel/nstandarditemmodel.hpp create mode 100644 src/cpp/include/nodegui/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.h create mode 100644 src/cpp/lib/QtWidgets/QStandardItem/qstandarditem_wrap.cpp create mode 100644 src/cpp/lib/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.cpp create mode 100644 src/lib/QtWidgets/QStandardItem.ts create mode 100644 src/lib/QtWidgets/QStandardItemModel.ts diff --git a/CMakeLists.txt b/CMakeLists.txt index a6abbabb7..60a24aa14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,6 +113,8 @@ add_library(${CORE_WIDGETS_ADDON} SHARED "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QButtonGroup/qbuttongroup_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QStatusBar/qstatusbar_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/core/FlexLayout/flexlayout_wrap.cpp" + "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.cpp" + "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QStandardItem/qstandarditem_wrap.cpp" # Custom widgets (include them for automoc since they contain Q_OBJECT) "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtCore/QObject/nobject.hpp" "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/core/FlexLayout/flexlayout.hpp" @@ -163,7 +165,7 @@ add_library(${CORE_WIDGETS_ADDON} SHARED "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QTreeWidget/ntreewidget.hpp" "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QButtonGroup/nbuttongroup.hpp" "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QStatusBar/nstatusbar.hpp" - + "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QStandardItemModel/nstandarditemmodel.hpp" ) AddCommonConfig(${CORE_WIDGETS_ADDON}) diff --git a/src/cpp/include/nodegui/QtWidgets/QComboBox/qcombobox_wrap.h b/src/cpp/include/nodegui/QtWidgets/QComboBox/qcombobox_wrap.h index 291fe7e62..a0f22d75c 100644 --- a/src/cpp/include/nodegui/QtWidgets/QComboBox/qcombobox_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QComboBox/qcombobox_wrap.h @@ -38,4 +38,6 @@ class DLL_EXPORT QComboBoxWrap : public Napi::ObjectWrap { Napi::Value isEditable(const Napi::CallbackInfo& info); Napi::Value setEditable(const Napi::CallbackInfo& info); Napi::Value clear(const Napi::CallbackInfo& info); + Napi::Value setModel(const Napi::CallbackInfo& info); + Napi::Value setEditText(const Napi::CallbackInfo& info); }; diff --git a/src/cpp/include/nodegui/QtWidgets/QStandardItem/qstandarditem_wrap.h b/src/cpp/include/nodegui/QtWidgets/QStandardItem/qstandarditem_wrap.h new file mode 100644 index 000000000..f51c6bb7c --- /dev/null +++ b/src/cpp/include/nodegui/QtWidgets/QStandardItem/qstandarditem_wrap.h @@ -0,0 +1,34 @@ +#pragma once + +#include + +#include + +#include "Extras/Export/export.h" +#include "core/Component/component_wrap.h" + +class DLL_EXPORT QStandardItemWrap + : public Napi::ObjectWrap { + COMPONENT_WRAPPED_METHODS_DECLARATION + private: + QStandardItem *instance; + bool disableDeletion; + + public: + static Napi::Object init(Napi::Env env, Napi::Object exports); + + QStandardItemWrap(const Napi::CallbackInfo &info); + + ~QStandardItemWrap(); + + QStandardItem *getInternalInstance(); + + // class constructor + static Napi::FunctionReference constructor; + + // wrapped methods + Napi::Value setCheckState(const Napi::CallbackInfo &info); + Napi::Value setData(const Napi::CallbackInfo &info); + Napi::Value setFlags(const Napi::CallbackInfo &info); + Napi::Value checkState(const Napi::CallbackInfo &info); +}; \ No newline at end of file diff --git a/src/cpp/include/nodegui/QtWidgets/QStandardItemModel/nstandarditemmodel.hpp b/src/cpp/include/nodegui/QtWidgets/QStandardItemModel/nstandarditemmodel.hpp new file mode 100644 index 000000000..5f8df278f --- /dev/null +++ b/src/cpp/include/nodegui/QtWidgets/QStandardItemModel/nstandarditemmodel.hpp @@ -0,0 +1,31 @@ +#pragma once +#include + +#include "Extras/Export/export.h" +#include "QtCore/QObject/qobject_macro.h" +#include "QtWidgets/QStandardItem/qstandarditem_wrap.h" +#include "core/NodeWidget/nodewidget.h" +#include "napi.h" + +class DLL_EXPORT NStandardItemModel : public QStandardItemModel, + public EventWidget { + Q_OBJECT + EVENTWIDGET_IMPLEMENTATIONS(QStandardItemModel) + public: + using QStandardItemModel::QStandardItemModel; // inherit all constructors of + // QStandardItemModel + void connectSignalsToEventEmitter() { + QOBJECT_SIGNALS + + QObject::connect( + this, &QStandardItemModel::itemChanged, [=](QStandardItem* item) { + Napi::Env env = this->emitOnNode.Env(); + Napi::HandleScope scope(env); + auto value = QStandardItemWrap::constructor.New( + {Napi::External::New(env, item), + Napi::Boolean::New(env, true)}); + this->emitOnNode.Call({Napi::String::New(env, "itemChanged"), value}); + }); + } + // Qt Connects: Implement all signal connects here +}; diff --git a/src/cpp/include/nodegui/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.h b/src/cpp/include/nodegui/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.h new file mode 100644 index 000000000..f4bbc5508 --- /dev/null +++ b/src/cpp/include/nodegui/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include + +#include "Extras/Export/export.h" +#include "QtCore/QObject/qobject_macro.h" +#include "nstandarditemmodel.hpp" +class DLL_EXPORT QStandardItemModelWrap + : public Napi::ObjectWrap { + private: + QPointer instance; + + public: + static Napi::Object init(Napi::Env env, Napi::Object exports); + QStandardItemModelWrap(const Napi::CallbackInfo& info); + ~QStandardItemModelWrap(); + NStandardItemModel* getInternalInstance(); + // class constructor + static Napi::FunctionReference constructor; + // wrapped methods + Napi::Value item(const Napi::CallbackInfo& info); + QOBJECT_WRAPPED_METHODS_DECLARATION +}; diff --git a/src/cpp/lib/QtWidgets/QComboBox/qcombobox_wrap.cpp b/src/cpp/lib/QtWidgets/QComboBox/qcombobox_wrap.cpp index c8fc3185d..5a2d990b4 100644 --- a/src/cpp/lib/QtWidgets/QComboBox/qcombobox_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QComboBox/qcombobox_wrap.cpp @@ -6,6 +6,8 @@ #include "Extras/Utils/nutils.h" #include "QtCore/QVariant/qvariant_wrap.h" #include "QtGui/QIcon/qicon_wrap.h" +#include "QtWidgets/QLineEdit/qlineedit_wrap.h" +#include "QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.h" #include "QtWidgets/QWidget/qwidget_wrap.h" Napi::FunctionReference QComboBoxWrap::constructor; @@ -33,6 +35,8 @@ Napi::Object QComboBoxWrap::init(Napi::Env env, Napi::Object exports) { InstanceMethod("isEditable", &QComboBoxWrap::isEditable), InstanceMethod("setEditable", &QComboBoxWrap::setEditable), InstanceMethod("clear", &QComboBoxWrap::clear), + InstanceMethod("setModel", &QComboBoxWrap::setModel), + InstanceMethod("setEditText", &QComboBoxWrap::setEditText), QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QComboBoxWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); @@ -243,3 +247,25 @@ Napi::Value QComboBoxWrap::clear(const Napi::CallbackInfo& info) { this->instance->clear(); return env.Null(); } + +Napi::Value QComboBoxWrap::setModel(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + Napi::Object itemObject = info[0].As(); + QStandardItemModelWrap* modelWrap = + Napi::ObjectWrap::Unwrap(itemObject); + QStandardItemModel* model = modelWrap->getInternalInstance(); + + this->instance->setModel(model); + return env.Null(); +} +Napi::Value QComboBoxWrap::setEditText(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + Napi::String text = info[0].As(); + this->instance->setEditText(text.Utf8Value().c_str()); + + return env.Null(); +} diff --git a/src/cpp/lib/QtWidgets/QStandardItem/qstandarditem_wrap.cpp b/src/cpp/lib/QtWidgets/QStandardItem/qstandarditem_wrap.cpp new file mode 100644 index 000000000..b26903d0f --- /dev/null +++ b/src/cpp/lib/QtWidgets/QStandardItem/qstandarditem_wrap.cpp @@ -0,0 +1,91 @@ +#include "QtWidgets/QStandardItem/qstandarditem_wrap.h" + +#include + +#include "Extras/Utils/nutils.h" +#include "QtWidgets/QStandardItem/qstandarditem_wrap.h" +#include "QtWidgets/QTreeWidget/qtreewidget_wrap.h" +#include "core/Component/component_wrap.h" + +Napi::FunctionReference QStandardItemWrap::constructor; + +Napi::Object QStandardItemWrap::init(Napi::Env env, Napi::Object exports) { + Napi::HandleScope scope(env); + char CLASSNAME[] = "QStandardItem"; + Napi::Function func = DefineClass( + env, CLASSNAME, + {InstanceMethod("setCheckState", &QStandardItemWrap::setCheckState), + InstanceMethod("setData", &QStandardItemWrap::setData), + InstanceMethod("setFlags", &QStandardItemWrap::setFlags), + InstanceMethod("checkState", &QStandardItemWrap::checkState), + COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE(QStandardItemWrap)}); + constructor = Napi::Persistent(func); + exports.Set(CLASSNAME, func); + return exports; +} + +QStandardItem* QStandardItemWrap::getInternalInstance() { + return this->instance; +} + +QStandardItemWrap::~QStandardItemWrap() { + if (!this->disableDeletion) { + delete this->instance; + } +} +QStandardItemWrap::QStandardItemWrap(const Napi::CallbackInfo& info) + : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + if (info.Length() > 0 && info[0].IsExternal()) { + this->instance = info[0].As>().Data(); + if (info.Length() == 2) { + this->disableDeletion = info[1].As().Value(); + } + } else { + if (info.Length() == 1) { + QString text = + QString::fromUtf8(info[0].As().Utf8Value().c_str()); + this->instance = new QStandardItem(text); + } else if (info.Length() == 0) { + this->instance = new QStandardItem(); + } else { + Napi::TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + } + } + this->rawData = extrautils::configureComponent(this->getInternalInstance()); +} + +Napi::Value QStandardItemWrap::setCheckState(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + int state = info[0].As().Int32Value(); + + this->instance->setCheckState(Qt::CheckState(state)); + return env.Null(); +} +Napi::Value QStandardItemWrap::setData(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + int value = info[0].As().Int32Value(); + int role = info[1].As().Int32Value(); + + this->instance->setData(value, role); + return env.Null(); +} +Napi::Value QStandardItemWrap::setFlags(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + int flags = info[0].As().Int32Value(); + + this->instance->setFlags(Qt::ItemFlag(flags)); + return env.Null(); +} +Napi::Value QStandardItemWrap::checkState(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + int state = static_cast(this->instance->checkState()); + return Napi::Number::From(env, state); +} diff --git a/src/cpp/lib/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.cpp b/src/cpp/lib/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.cpp new file mode 100644 index 000000000..991fefa1a --- /dev/null +++ b/src/cpp/lib/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.cpp @@ -0,0 +1,70 @@ +#include "QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.h" + +#include +#include + +#include "Extras/Utils/nutils.h" +#include "QtCore/QObject/qobject_wrap.h" +#include "QtGui/QIcon/qicon_wrap.h" +#include "QtWidgets/QMenu/qmenu_wrap.h" +#include "QtWidgets/QStandardItem/qstandarditem_wrap.h" +#include "QtWidgets/QWidget/qwidget_wrap.h" + +Napi::FunctionReference QStandardItemModelWrap::constructor; + +Napi::Object QStandardItemModelWrap::init(Napi::Env env, Napi::Object exports) { + Napi::HandleScope scope(env); + char CLASSNAME[] = "QStandardItemModel"; + Napi::Function func = DefineClass( + env, CLASSNAME, + {InstanceMethod("item", &QStandardItemModelWrap::item), + + QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QStandardItemModelWrap)}); + constructor = Napi::Persistent(func); + exports.Set(CLASSNAME, func); + return exports; +} + +NStandardItemModel* QStandardItemModelWrap::getInternalInstance() { + return this->instance; +} + +QStandardItemModelWrap::QStandardItemModelWrap(const Napi::CallbackInfo& info) + : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + if (info.Length() == 1) { + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NStandardItemModel( + parentWidgetWrap + ->getInternalInstance()); // this sets the parent to current widget + } else if (info.Length() == 0) { + this->instance = new NStandardItemModel(); + } else { + Napi::TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + } + this->rawData = extrautils::configureQObject(this->getInternalInstance()); +} + +QStandardItemModelWrap::~QStandardItemModelWrap() {} + +Napi::Value QStandardItemModelWrap::item(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + int row = info[0].As().Int32Value(); + int column = info[1].As().Int32Value(); + + QStandardItem* item = this->instance->item(row, column); + if (item != nullptr) { + Napi::Object itemWrap = QStandardItemWrap::constructor.New( + {Napi::External::New(env, item), + Napi::Boolean::New(env, true)}); + return itemWrap; + } else { + return env.Null(); + } +} diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index 5ca3ba9f2..8cf29c7bc 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -63,6 +63,8 @@ #include "QtWidgets/QSlider/qslider_wrap.h" #include "QtWidgets/QSpinBox/qspinbox_wrap.h" #include "QtWidgets/QStackedWidget/qstackedwidget_wrap.h" +#include "QtWidgets/QStandardItem/qstandarditem_wrap.h" +#include "QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.h" #include "QtWidgets/QStatusBar/qstatusbar_wrap.h" #include "QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.h" #include "QtWidgets/QTabBar/qtabbar_wrap.h" @@ -160,6 +162,8 @@ Napi::Object Main(Napi::Env env, Napi::Object exports) { QButtonGroupWrap::init(env, exports); QStatusBarWrap::init(env, exports); QSettingsWrap::init(env, exports); + QStandardItemModelWrap::init(env, exports); + QStandardItemWrap::init(env, exports); return exports; } diff --git a/src/index.ts b/src/index.ts index 57f939390..bc3809c55 100644 --- a/src/index.ts +++ b/src/index.ts @@ -85,6 +85,7 @@ export { QAction, QActionSignals } from './lib/QtWidgets/QAction'; export { QShortcut, QShortcutSignals } from './lib/QtWidgets/QShortcut'; export { QGroupBox, QGroupBoxSignals } from './lib/QtWidgets/QGroupBox'; export { QStatusBar, QStatusBarSignals } from './lib/QtWidgets/QStatusBar'; +export { QStandardItemModel, QStandardItemModelSignals } from './lib/QtWidgets/QStandardItemModel'; // Core export { QDate } from './lib/QtCore/QDate'; export { QDateTime } from './lib/QtCore/QDateTime'; diff --git a/src/lib/QtWidgets/QComboBox.ts b/src/lib/QtWidgets/QComboBox.ts index 48f9d155e..2bf2a6552 100644 --- a/src/lib/QtWidgets/QComboBox.ts +++ b/src/lib/QtWidgets/QComboBox.ts @@ -4,6 +4,7 @@ import { NativeElement } from '../core/Component'; import { SizeAdjustPolicy } from '../QtEnums'; import { QIcon } from '../QtGui/QIcon'; import { QVariant } from '../QtCore/QVariant'; +import { QStandardItemModel } from './QStandardItemModel'; /** @@ -113,6 +114,12 @@ export class QComboBox extends NodeWidget { setCurrentIndex(index: number): void { this.setProperty('currentIndex', index); } + setModel(model: QStandardItemModel): void { + this.native.setModel(model.native); + } + setEditText(text: string): void { + this.native.setEditText(text); + } } export enum InsertPolicy { diff --git a/src/lib/QtWidgets/QStandardItem.ts b/src/lib/QtWidgets/QStandardItem.ts new file mode 100644 index 000000000..bb9be5d81 --- /dev/null +++ b/src/lib/QtWidgets/QStandardItem.ts @@ -0,0 +1,36 @@ +import addon from '../utils/addon'; +import { Component, NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; +import { ItemFlag } from '../QtEnums/ItemFlag'; +import { CheckState } from '../QtEnums'; + +export class QStandardItem extends Component { + native: NativeElement; + constructor(); + constructor(parent: QStandardItem, text?: string); + constructor(native: NativeElement); + constructor(parent?: NativeElement | QStandardItem, text?: string) { + super(); + if (checkIfNativeElement(parent)) { + this.native = parent as NativeElement; + } else { + if (text) { + this.native = new addon.QStandardItem(text); + } else { + this.native = new addon.QStandardItem(); + } + } + } + setCheckState(state: CheckState): void { + this.native.setCheckState(state); + } + setFlags(flags: ItemFlag): void { + this.native.setFlags(flags); + } + setData(value: number, role: number): void { + this.native.setData(value, role); + } + checkState(): CheckState { + return this.native.checkState(); + } +} diff --git a/src/lib/QtWidgets/QStandardItemModel.ts b/src/lib/QtWidgets/QStandardItemModel.ts new file mode 100644 index 000000000..b09db9406 --- /dev/null +++ b/src/lib/QtWidgets/QStandardItemModel.ts @@ -0,0 +1,34 @@ +import addon from '../utils/addon'; +import { NodeWidget } from './QWidget'; +import { NativeElement } from '../core/Component'; +import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QStandardItem } from './QStandardItem'; + +export interface QStandardItemModelSignals extends QObjectSignals { + itemChanged: (item: QStandardItem) => void; +} + +export class QStandardItemModel extends NodeObject { + native: NativeElement; + constructor(); + constructor(parent: NodeWidget); + constructor(parent?: NodeWidget) { + let native; + if (parent) { + native = new addon.QStandardItemModel(parent.native); + } else { + native = new addon.QStandardItemModel(); + } + super(native); + this.native = native; + parent && parent.nodeChildren.add(this); + } + item(row: number, column = 0): QStandardItem | void { + const item = this.native.item(row, column); + if (item) { + return new QStandardItem(item); + } else { + return undefined; + } + } +}