diff --git a/CMakeLists.txt b/CMakeLists.txt index c6e406067..ff717086b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ add_library(${CORE_WIDGETS_ADDON} SHARED "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtCore/QUrl/qurl_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QBoxLayout/qboxlayout_wrap.cpp" + "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QComboBox/qcombobox_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QGridLayout/qgridlayout_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QDial/qdial_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp" @@ -99,6 +100,7 @@ add_library(${CORE_WIDGETS_ADDON} SHARED "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QLayout/nlayout.hpp" "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QGridLayout/ngridlayout.hpp" "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QBoxLayout/nboxlayout.hpp" + "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QComboBox/ncombobox.hpp" ) AddCommonConfig(${CORE_WIDGETS_ADDON}) diff --git a/src/cpp/include/nodegui/QtWidgets/QComboBox/ncombobox.hpp b/src/cpp/include/nodegui/QtWidgets/QComboBox/ncombobox.hpp new file mode 100644 index 000000000..76ca4d4f5 --- /dev/null +++ b/src/cpp/include/nodegui/QtWidgets/QComboBox/ncombobox.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include "core/NodeWidget/nodewidget.h" +#include "napi.h" + +class NComboBox : public QComboBox, public NodeWidget { + public: + Q_OBJECT + NODEWIDGET_IMPLEMENTATIONS(QComboBox) + using QComboBox::QComboBox; + + void connectWidgetSignalsToEventEmitter() { + // Qt Connects: Implement all signal connects here + QObject::connect( + this, QOverload::of(&QComboBox::currentIndexChanged), + [=](int index) { + Napi::Env env = this->emitOnNode.Env(); + Napi::HandleScope scope(env); + this->emitOnNode.Call({Napi::String::New(env, "currentIndexChanged"), + Napi::Number::From(env, index)}); + }); + QObject::connect( + this, QOverload::of(&QComboBox::currentTextChanged), + [=](const QString &text) { + Napi::Env env = this->emitOnNode.Env(); + Napi::HandleScope scope(env); + this->emitOnNode.Call({Napi::String::New(env, "currentTextChanged"), + Napi::String::New(env, text.toStdString())}); + }); + QObject::connect( + this, &QComboBox::editTextChanged, [=](const QString &text) { + Napi::Env env = this->emitOnNode.Env(); + Napi::HandleScope scope(env); + this->emitOnNode.Call({Napi::String::New(env, "editTextChanged"), + Napi::String::New(env, text.toStdString())}); + }); + } +}; diff --git a/src/cpp/include/nodegui/QtWidgets/QComboBox/qcombobox_wrap.h b/src/cpp/include/nodegui/QtWidgets/QComboBox/qcombobox_wrap.h new file mode 100644 index 000000000..028d42f08 --- /dev/null +++ b/src/cpp/include/nodegui/QtWidgets/QComboBox/qcombobox_wrap.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include + +#include + +#include "Extras/Utils/nutils.h" +#include "QtWidgets/QComboBox/ncombobox.hpp" +#include "QtWidgets/QWidget/qwidget_macro.h" + +class QComboBoxWrap : public Napi::ObjectWrap { + private: + QPointer instance; + + public: + static Napi::Object init(Napi::Env env, Napi::Object exports); + QComboBoxWrap(const Napi::CallbackInfo& info); + ~QComboBoxWrap(); + NComboBox* getInternalInstance(); + // class constructor + static Napi::FunctionReference constructor; + // wrapped methods + Napi::Value addItem(const Napi::CallbackInfo& info); + Napi::Value insertItem(const Napi::CallbackInfo& info); + Napi::Value currentIndex(const Napi::CallbackInfo& info); + Napi::Value currentText(const Napi::CallbackInfo& info); + Napi::Value insertSeparator(const Napi::CallbackInfo& info); + Napi::Value itemText(const Napi::CallbackInfo& info); + Napi::Value removeItem(const Napi::CallbackInfo& info); + Napi::Value sizeAdjustPolicy(const Napi::CallbackInfo& info); + Napi::Value setSizeAdjustPolicy(const Napi::CallbackInfo& info); + Napi::Value maxVisibleItems(const Napi::CallbackInfo& info); + Napi::Value setMaxVisibleItems(const Napi::CallbackInfo& info); + Napi::Value isEditable(const Napi::CallbackInfo& info); + Napi::Value setEditable(const Napi::CallbackInfo& info); + + QWIDGET_WRAPPED_METHODS_DECLARATION +}; diff --git a/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp b/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp index 0b20a03b4..026f90f08 100644 --- a/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp +++ b/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp @@ -106,8 +106,7 @@ Napi::Value StaticQApplicationWrapMethods::style( Napi::Env env = info.Env(); Napi::HandleScope scope(env); QStyle* style = QApplication::style(); - return QStyleWrap::constructor.New( - {Napi::External::New(env, style)}); + return QStyleWrap::constructor.New({Napi::External::New(env, style)}); } Napi::Value QApplicationWrap::setQuitOnLastWindowClosed( diff --git a/src/cpp/lib/QtWidgets/QComboBox/qcombobox_wrap.cpp b/src/cpp/lib/QtWidgets/QComboBox/qcombobox_wrap.cpp new file mode 100644 index 000000000..e82c9c908 --- /dev/null +++ b/src/cpp/lib/QtWidgets/QComboBox/qcombobox_wrap.cpp @@ -0,0 +1,172 @@ + +#include "QtWidgets/QComboBox/qcombobox_wrap.h" + +#include + +#include "Extras/Utils/nutils.h" +#include "QtWidgets/QWidget/qwidget_wrap.h" + +Napi::FunctionReference QComboBoxWrap::constructor; + +Napi::Object QComboBoxWrap::init(Napi::Env env, Napi::Object exports) { + Napi::HandleScope scope(env); + char CLASSNAME[] = "QComboBox"; + Napi::Function func = DefineClass( + env, CLASSNAME, + {InstanceMethod("addItem", &QComboBoxWrap::addItem), + InstanceMethod("insertItem", &QComboBoxWrap::insertItem), + InstanceMethod("currentIndex", &QComboBoxWrap::currentIndex), + InstanceMethod("currentText", &QComboBoxWrap::currentText), + InstanceMethod("insertSeparator", &QComboBoxWrap::insertSeparator), + InstanceMethod("itemText", &QComboBoxWrap::itemText), + InstanceMethod("removeItem", &QComboBoxWrap::removeItem), + InstanceMethod("sizeAdjustPolicy", &QComboBoxWrap::sizeAdjustPolicy), + InstanceMethod("setSizeAdjustPolicy", + &QComboBoxWrap::setSizeAdjustPolicy), + InstanceMethod("maxVisibleItems", &QComboBoxWrap::maxVisibleItems), + InstanceMethod("setMaxVisibleItems", &QComboBoxWrap::setMaxVisibleItems), + InstanceMethod("isEditable", &QComboBoxWrap::isEditable), + InstanceMethod("setEditable", &QComboBoxWrap::setEditable), + QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QComboBoxWrap)}); + constructor = Napi::Persistent(func); + exports.Set(CLASSNAME, func); + return exports; +} + +NComboBox* QComboBoxWrap::getInternalInstance() { return this->instance; } +QComboBoxWrap::~QComboBoxWrap() { extrautils::safeDelete(this->instance); } + +QComboBoxWrap::QComboBoxWrap(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(); + QWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + + this->instance = new NComboBox(parentWidgetWrap->getInternalInstance()); + } else if (info.Length() == 0) { + this->instance = new NComboBox(); + } else { + Napi::TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + } + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); +} + +Napi::Value QComboBoxWrap::addItem(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + std::string text = info[0].As().Utf8Value(); + + this->instance->addItem(text.c_str()); + return env.Null(); +} + +Napi::Value QComboBoxWrap::insertItem(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int index = info[0].As().Int32Value(); + std::string text = info[1].As().Utf8Value(); + + this->instance->insertItem(index, text.c_str()); + return env.Null(); +} + +Napi::Value QComboBoxWrap::currentIndex(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, this->instance->currentIndex()); +} + +Napi::Value QComboBoxWrap::currentText(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::String::New(env, this->instance->currentText().toStdString()); +} + +Napi::Value QComboBoxWrap::insertSeparator(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int index = info[0].As().Int32Value(); + + this->instance->insertSeparator(index); + return env.Null(); +} + +Napi::Value QComboBoxWrap::itemText(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int index = info[0].As().Int32Value(); + + return Napi::String::New(env, this->instance->itemText(index).toStdString()); +} + +Napi::Value QComboBoxWrap::removeItem(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int index = info[0].As().Int32Value(); + + this->instance->removeItem(index); + return env.Null(); +} + +Napi::Value QComboBoxWrap::sizeAdjustPolicy(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, this->instance->sizeAdjustPolicy()); +} +Napi::Value QComboBoxWrap::setSizeAdjustPolicy(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + QComboBox::SizeAdjustPolicy policy = static_cast( + info[0].As().Int32Value()); + this->instance->setSizeAdjustPolicy(policy); + return env.Null(); +} + +Napi::Value QComboBoxWrap::maxVisibleItems(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Number::New(env, this->instance->maxVisibleItems()); +} + +Napi::Value QComboBoxWrap::setMaxVisibleItems(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + int maxItems = info[0].As().Int32Value(); + + this->instance->setMaxVisibleItems(maxItems); + return env.Null(); +} + +Napi::Value QComboBoxWrap::isEditable(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + return Napi::Boolean::New(env, this->instance->isEditable()); +} + +Napi::Value QComboBoxWrap::setEditable(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + bool editable = info[0].As().Value(); + + this->instance->setEditable(editable); + return env.Null(); +} diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index b5a90d234..db9c1d195 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -18,6 +18,7 @@ #include "QtWidgets/QAction/qaction_wrap.h" #include "QtWidgets/QBoxLayout/qboxlayout_wrap.h" #include "QtWidgets/QCheckBox/qcheckbox_wrap.h" +#include "QtWidgets/QComboBox/qcombobox_wrap.h" #include "QtWidgets/QDial/qdial_wrap.h" #include "QtWidgets/QGridLayout/qgridlayout_wrap.h" #include "QtWidgets/QLabel/qlabel_wrap.h" @@ -60,6 +61,7 @@ Napi::Object Main(Napi::Env env, Napi::Object exports) { QMovieWrap::init(env, exports); QStyleWrap::init(env, exports); QCursorWrap::init(env, exports); + QComboBoxWrap::init(env, exports); QBoxLayoutWrap::init(env, exports); QGridLayoutWrap::init(env, exports); FlexLayoutWrap::init(env, exports); diff --git a/src/demo.ts b/src/demo.ts index 14d44d5ec..e7e74198c 100644 --- a/src/demo.ts +++ b/src/demo.ts @@ -1,6 +1,9 @@ import { QWidget, QScrollArea, FlexLayout, QPushButton } from './index'; import { QLabel } from './lib/QtWidgets/QLabel'; import { QMainWindow } from './lib/QtWidgets/QMainWindow'; +import { QComboBox, QComboBoxEvents } from './lib/QtWidgets/QComboBox'; + +import { SizeAdjustPolicy } from './lib/QtEnums'; const win = new QMainWindow(); const scroll = new QScrollArea(); @@ -15,6 +18,50 @@ btn.setText('helloo'); const text = new QLabel(); text.setText('1 oncererer'); +const combo = new QComboBox(); +combo.addItem('test'); +combo.addItem('test2'); +combo.addEventListener(QComboBoxEvents.currentTextChanged, e => { + console.log('text changed', e); +}); +combo.addEventListener(QComboBoxEvents.currentIndexChanged, e => { + console.log('index changed', e); +}); +combo.addEventListener(QComboBoxEvents.editTextChanged, e => { + console.log('edit changed', e); +}); +const btn1 = new QPushButton(); +const btn2 = new QPushButton(); +const btn3 = new QPushButton(); +const btn4 = new QPushButton(); +const btn5 = new QPushButton(); + +btn1.setText('add to index 1'); +btn1.addEventListener('clicked', () => { + combo.insertItem(1, 'inserted'); +}); +btn2.setText('remove index 1'); +btn2.addEventListener('clicked', () => { + combo.removeItem(1); +}); +btn3.setText('editable'); +btn3.addEventListener('clicked', () => { + combo.setEditable(!combo.isEditable()); +}); +btn4.setText('max 4'); +btn4.addEventListener('clicked', () => { + combo.setMaxVisibleItems(4); +}); +btn5.setText('Adjust Size'); +btn5.addEventListener('clicked', () => { + combo.setSizeAdjustPolicy(SizeAdjustPolicy.AdjustToContents); +}); +center.layout?.addWidget(combo); +center.layout?.addWidget(btn1); +center.layout?.addWidget(btn2); +center.layout?.addWidget(btn3); +center.layout?.addWidget(btn4); +center.layout?.addWidget(btn5); btn.addEventListener('clicked', () => { text.setText(` Yoloooooooooo diff --git a/src/index.ts b/src/index.ts index d39baf223..fab887f0f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -30,6 +30,7 @@ export { QDial, QDialEvents } from './lib/QtWidgets/QDial'; export { QLineEdit, QLineEditEvents, EchoMode } from './lib/QtWidgets/QLineEdit'; export { QMainWindow, QMainWindowEvents } from './lib/QtWidgets/QMainWindow'; export { QProgressBar, QProgressBarEvents } from './lib/QtWidgets/QProgressBar'; +export { QComboBox, QComboBoxEvents } from './lib/QtWidgets/QComboBox'; export { QPushButton, QPushButtonEvents } from './lib/QtWidgets/QPushButton'; export { QSpinBox, QSpinBoxEvents } from './lib/QtWidgets/QSpinBox'; export { QRadioButton, QRadioButtonEvents } from './lib/QtWidgets/QRadioButton'; diff --git a/src/lib/QtEnums/SizeAdjustPolicy/index.ts b/src/lib/QtEnums/SizeAdjustPolicy/index.ts new file mode 100644 index 000000000..7c7120c4a --- /dev/null +++ b/src/lib/QtEnums/SizeAdjustPolicy/index.ts @@ -0,0 +1,6 @@ +export enum SizeAdjustPolicy { + AdjustToContents = 0, + AdjustToContentsOnFirstShow = 1, + AdjustToMinimumContentsLength = 2, + AdjustToMinimumContentsLengthWithIcon = 3, +} diff --git a/src/lib/QtEnums/index.ts b/src/lib/QtEnums/index.ts index 3316c5b9a..874256fcc 100644 --- a/src/lib/QtEnums/index.ts +++ b/src/lib/QtEnums/index.ts @@ -57,6 +57,7 @@ export { ScreenOrientation } from './ScreenOrientation'; export { ScrollBarPolicy } from './ScrollBarPolicy'; export { ScrollPhase } from './ScrollPhase'; export { ShortcutContext } from './ShortcutContext'; +export { SizeAdjustPolicy } from './SizeAdjustPolicy'; export { SizeHint } from './SizeHint'; export { SizeMode } from './SizeMode'; export { SortOrder } from './SortOrder'; diff --git a/src/lib/QtWidgets/QComboBox.ts b/src/lib/QtWidgets/QComboBox.ts new file mode 100644 index 000000000..2c8d0ed2e --- /dev/null +++ b/src/lib/QtWidgets/QComboBox.ts @@ -0,0 +1,65 @@ +import addon from '../utils/addon'; +import { NodeWidget } from './QWidget'; +import { BaseWidgetEvents } from '../core/EventWidget'; +import { NativeElement } from '../core/Component'; +import { SizeAdjustPolicy } from '../QtEnums'; + +export const QComboBoxEvents = Object.freeze({ + currentIndexChanged: 'currentIndexChanged', + currentTextChanged: 'currentTextChanged', + editTextChanged: 'editTextChanged', + ...BaseWidgetEvents, +}); +export class QComboBox extends NodeWidget { + native: NativeElement; + constructor(parent?: NodeWidget) { + let native; + if (parent) { + native = new addon.QComboBox(parent.native); + } else { + native = new addon.QComboBox(); + } + super(native); + this.native = native; + this.nodeParent = parent; + } + addItem(value: string): void { + this.native.addItem(value); + } + insertItem(index: number, text: string): void { + this.native.insertItem(index, text); + } + currentIndex(): number { + return this.native.currentIndex(); + } + currentText(): string { + return this.native.currentText(); + } + insertSeparator(index: number): void { + this.native.insertSeparator(index); + } + itemText(index: number): void { + this.native.itemText(index); + } + removeItem(index: number): void { + this.native.removeItem(index); + } + sizeAdjustPolicy(): number { + return this.native.sizeAdjustPolicy(); + } + setSizeAdjustPolicy(policy: SizeAdjustPolicy): void { + this.native.setSizeAdjustPolicy(policy); + } + maxVisibleItems(): number { + return this.native.maxVisibleItems(); + } + setMaxVisibleItems(index: number): void { + this.native.setMaxVisibleItems(index); + } + isEditable(): boolean { + return this.native.isEditable(); + } + setEditable(editable: boolean): void { + this.native.setEditable(editable); + } +}