From edcdbb510ef629f9da48f44020a75db4c3ad008b Mon Sep 17 00:00:00 2001 From: Atul R Date: Mon, 18 Nov 2019 00:52:29 +0100 Subject: [PATCH] Adds dynamic content support for flex layout. (#199) * layout performance fix * adjust size, webdefaults * Add flexlayout owner to the context * revert * reorders setlayout and setflexnode * add defaults * fix mainwindow rootNode * properties to methods * Adds defaultsAdds flexutils measurewidget * introduce configure for all types of nodes. * lint fix * Revams flexlayout to handle dynamic content * Adds dynamic layout support for flex layout. * lint fix * fix few code updates --- CMakeLists.txt | 1 + src/cpp/include/nodegui/Extras/Utils/nutils.h | 10 +- .../QEvent/QMouseEvent/qmouseevent_wrap.h | 1 - .../nodegui/QtWidgets/QLabel/qlabel_wrap.h | 4 +- .../QtWidgets/QScrollArea/qscrollarea_wrap.h | 1 + .../nodegui/QtWidgets/QWidget/qwidget_macro.h | 9 +- .../nodegui/core/FlexLayout/flexlayout.h | 7 +- .../nodegui/core/FlexLayout/flexutils.h | 27 +++ src/cpp/lib/Extras/Utils/nutils.cpp | 33 +-- src/cpp/lib/QtCore/QObject/qobject_wrap.cpp | 2 +- src/cpp/lib/QtCore/QSize/qsize_wrap.cpp | 2 +- src/cpp/lib/QtCore/QVariant/qvariant_wrap.cpp | 2 +- .../QtGui/QApplication/qapplication_wrap.cpp | 2 +- .../lib/QtGui/QClipboard/qclipboard_wrap.cpp | 2 +- src/cpp/lib/QtGui/QCursor/qcursor_wrap.cpp | 2 +- .../QtGui/QEvent/QKeyEvent/qkeyevent_wrap.cpp | 2 +- .../QEvent/QMouseEvent/qmouseevent_wrap.cpp | 18 +- src/cpp/lib/QtGui/QIcon/qicon_wrap.cpp | 2 +- .../QtGui/QKeySequence/qkeysequence_wrap.cpp | 2 +- src/cpp/lib/QtGui/QPixmap/qpixmap_wrap.cpp | 2 +- .../lib/QtWidgets/QAction/qaction_wrap.cpp | 2 +- .../QtWidgets/QCheckBox/qcheckbox_wrap.cpp | 8 +- src/cpp/lib/QtWidgets/QDial/qdial_wrap.cpp | 9 +- .../QGridLayout/qgridlayout_wrap.cpp | 2 +- src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp | 9 +- .../QtWidgets/QLineEdit/qlineedit_wrap.cpp | 8 +- .../QMainWindow/qmainwindow_wrap.cpp | 14 +- src/cpp/lib/QtWidgets/QMenu/qmenu_wrap.cpp | 8 +- .../lib/QtWidgets/QMenuBar/qmenubar_wrap.cpp | 7 +- .../QPlainTextEdit/qplaintextedit_wrap.cpp | 8 +- .../QProgressBar/qprogressbar_wrap.cpp | 8 +- .../QPushButton/qpushbutton_wrap.cpp | 7 +- .../QRadioButton/qradiobutton_wrap.cpp | 8 +- .../QScrollArea/qscrollarea_wrap.cpp | 16 +- .../QtWidgets/QShortcut/qshortcut_wrap.cpp | 2 +- .../lib/QtWidgets/QSpinBox/qspinbox_wrap.cpp | 8 +- .../QSystemTrayIcon/qsystemtrayicon_wrap.cpp | 2 +- .../QtWidgets/QTabWidget/qtabwidget_wrap.cpp | 8 +- .../lib/QtWidgets/QWidget/qwidget_wrap.cpp | 4 +- src/cpp/lib/core/FlexLayout/flexitem.cpp | 14 +- src/cpp/lib/core/FlexLayout/flexlayout.cpp | 196 ++++++++---------- .../lib/core/FlexLayout/flexlayout_wrap.cpp | 2 +- src/cpp/lib/core/FlexLayout/flexutils.cpp | 70 +++++++ src/demo.ts | 87 ++++---- src/lib/QtGui/QEvent/QKeyEvent.ts | 20 +- src/lib/QtGui/QEvent/QMouseEvent.ts | 20 +- src/lib/QtGui/QIcon.ts | 6 +- src/lib/QtWidgets/QLayout.ts | 4 +- src/lib/QtWidgets/QScrollArea.ts | 2 +- src/lib/QtWidgets/QWidget.ts | 5 +- src/lib/core/Style/StyleSheet.ts | 4 +- src/lib/core/YogaWidget.ts | 4 +- website/docs/development/common_errors.md | 2 +- 53 files changed, 390 insertions(+), 315 deletions(-) create mode 100644 src/cpp/include/nodegui/core/FlexLayout/flexutils.h create mode 100644 src/cpp/lib/core/FlexLayout/flexutils.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ea430fc28..61ffcd228 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ add_library(${CORE_WIDGETS_ADDON} SHARED "${PROJECT_SOURCE_DIR}/src/cpp/main.cpp" # core internals "${PROJECT_SOURCE_DIR}/src/cpp/lib/Extras/Utils/nutils.cpp" + "${PROJECT_SOURCE_DIR}/src/cpp/lib/core/FlexLayout/flexutils.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/core/FlexLayout/flexlayout.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/core/FlexLayout/flexitem.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/core/YogaWidget/nodestyle.cpp" diff --git a/src/cpp/include/nodegui/Extras/Utils/nutils.h b/src/cpp/include/nodegui/Extras/Utils/nutils.h index 5f3550e7d..9dda6d7b2 100644 --- a/src/cpp/include/nodegui/Extras/Utils/nutils.h +++ b/src/cpp/include/nodegui/Extras/Utils/nutils.h @@ -6,16 +6,16 @@ #include #include "core/FlexLayout/flexlayout.h" - +#include "core/FlexLayout/flexutils.h" namespace extrautils { -YGSize measureQtWidget(YGNodeRef node, float width, YGMeasureMode widthMode, - float height, YGMeasureMode heightMode); QVariant* convertToQVariant(Napi::Env& env, Napi::Value& value); - bool isNapiValueInt(Napi::Env& env, Napi::Value& num); - std::string getNapiObjectClassName(Napi::Object& object); +void* configureQWidget(QWidget* widget, YGNodeRef node, + bool isLeafNode = false); +void* configureQObject(QObject* object); +void* configureComponent(void* component); template void safeDelete(QPointer& component) { diff --git a/src/cpp/include/nodegui/QtGui/QEvent/QMouseEvent/qmouseevent_wrap.h b/src/cpp/include/nodegui/QtGui/QEvent/QMouseEvent/qmouseevent_wrap.h index fc3128664..83fc97ddc 100644 --- a/src/cpp/include/nodegui/QtGui/QEvent/QMouseEvent/qmouseevent_wrap.h +++ b/src/cpp/include/nodegui/QtGui/QEvent/QMouseEvent/qmouseevent_wrap.h @@ -25,6 +25,5 @@ class QMouseEventWrap : public Napi::ObjectWrap { Napi::Value globalX(const Napi::CallbackInfo& info); Napi::Value globalY(const Napi::CallbackInfo& info); - COMPONENT_WRAPPED_METHODS_DECLARATION }; \ No newline at end of file diff --git a/src/cpp/include/nodegui/QtWidgets/QLabel/qlabel_wrap.h b/src/cpp/include/nodegui/QtWidgets/QLabel/qlabel_wrap.h index fda4ede8b..bc2fba867 100644 --- a/src/cpp/include/nodegui/QtWidgets/QLabel/qlabel_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QLabel/qlabel_wrap.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include @@ -13,6 +12,7 @@ class QLabelWrap : public Napi::ObjectWrap { QPointer instance; public: + QWIDGET_WRAPPED_METHODS_DECLARATION static Napi::Object init(Napi::Env env, Napi::Object exports); QLabelWrap(const Napi::CallbackInfo& info); ~QLabelWrap(); @@ -26,6 +26,4 @@ class QLabelWrap : public Napi::ObjectWrap { Napi::Value text(const Napi::CallbackInfo& info); Napi::Value setPixmap(const Napi::CallbackInfo& info); Napi::Value setOpenExternalLinks(const Napi::CallbackInfo& info); - - QWIDGET_WRAPPED_METHODS_DECLARATION }; diff --git a/src/cpp/include/nodegui/QtWidgets/QScrollArea/qscrollarea_wrap.h b/src/cpp/include/nodegui/QtWidgets/QScrollArea/qscrollarea_wrap.h index 7ce0a7b3c..396d9f966 100644 --- a/src/cpp/include/nodegui/QtWidgets/QScrollArea/qscrollarea_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QScrollArea/qscrollarea_wrap.h @@ -11,6 +11,7 @@ class QScrollAreaWrap : public Napi::ObjectWrap { private: QPointer instance; + YGNodeRef scrollNode; public: static Napi::Object init(Napi::Env env, Napi::Object exports); diff --git a/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h b/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h index f7523b2d8..aebe21070 100644 --- a/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h +++ b/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h @@ -262,6 +262,12 @@ this->instance->setWindowFlag(static_cast(windowType), \ switchOn); \ return env.Null(); \ + } \ + Napi::Value adjustSize(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::HandleScope scope(env); \ + this->instance->adjustSize(); \ + return env.Null(); \ } #endif // QWIDGET_WRAPPED_METHODS_DECLARATION @@ -302,6 +308,7 @@ InstanceMethod("testAttribute", &WidgetWrapName::testAttribute), \ InstanceMethod("setWindowOpacity", &WidgetWrapName::setWindowOpacity), \ InstanceMethod("windowOpacity", &WidgetWrapName::windowOpacity), \ - InstanceMethod("setWindowFlag", &WidgetWrapName::setWindowFlag), + InstanceMethod("setWindowFlag", &WidgetWrapName::setWindowFlag), \ + InstanceMethod("adjustSize", &WidgetWrapName::adjustSize), #endif // QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE diff --git a/src/cpp/include/nodegui/core/FlexLayout/flexlayout.h b/src/cpp/include/nodegui/core/FlexLayout/flexlayout.h index ce94f1ae0..c95f7c728 100644 --- a/src/cpp/include/nodegui/core/FlexLayout/flexlayout.h +++ b/src/cpp/include/nodegui/core/FlexLayout/flexlayout.h @@ -21,13 +21,9 @@ YGNodeNew(); FlexLayout * flayout = new FlexLayout(container,root); class FlexLayout : public QLayout, public EventWidget { private: YGNodeRef node; - YGNodeRef getRootNode(YGNodeRef node); + YGNodeRef getRootNode(YGNodeRef node) const; public: - struct NodeContext { - NodeContext(QLayoutItem *i) { item = i; } - QLayoutItem *item; - }; FlexLayout(QWidget *parentWidget = nullptr, YGNodeRef parentNode = nullptr); ~FlexLayout() override; QSize sizeHint() const override; @@ -41,7 +37,6 @@ class FlexLayout : public QLayout, public EventWidget { void removeWidget(QWidget *childWidget, YGNodeRef childNode); void setGeometry(const QRect &rect) override; void setFlexNode(YGNodeRef parentNode); - static NodeContext *getNodeContext(YGNodeRef node); EVENTWIDGET_IMPLEMENTATIONS(FlexLayout) }; diff --git a/src/cpp/include/nodegui/core/FlexLayout/flexutils.h b/src/cpp/include/nodegui/core/FlexLayout/flexutils.h new file mode 100644 index 000000000..01b6458e9 --- /dev/null +++ b/src/cpp/include/nodegui/core/FlexLayout/flexutils.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +#include "deps/yoga/YGNode.h" + +class FlexNodeContext { + void* _widget; + QLayoutItem* _layoutItem; + + public: + FlexNodeContext(void* widget); + QWidget* widget(); + QLayoutItem* layoutItem(); + void setLayoutItem(QLayoutItem* item); +}; +namespace flexutils { +YGSize measureQtWidget(YGNodeRef node, float width, YGMeasureMode widthMode, + float height, YGMeasureMode heightMode); +const QRect getFlexNodeGeometry(YGNodeRef node); +void setFlexNodeGeometry(YGNodeRef node, const QRect& geometry); +FlexNodeContext* getFlexNodeContext(YGNodeRef node); +void configureFlexNode(QWidget* widget, YGNodeRef node, + bool isLeafNode = false); + +} // namespace flexutils \ No newline at end of file diff --git a/src/cpp/lib/Extras/Utils/nutils.cpp b/src/cpp/lib/Extras/Utils/nutils.cpp index 056d24b4d..8624a950f 100644 --- a/src/cpp/lib/Extras/Utils/nutils.cpp +++ b/src/cpp/lib/Extras/Utils/nutils.cpp @@ -5,28 +5,7 @@ #include #include "core/Component/component_wrap.h" - -YGSize extrautils::measureQtWidget(YGNodeRef node, float width, - YGMeasureMode widthMode, float height, - YGMeasureMode heightMode) { - FlexLayout::NodeContext* ctx = FlexLayout::getNodeContext(node); - if (ctx) { - QLayoutItem* childLayoutItem = ctx->item; - QWidget* widget = childLayoutItem->widget(); - float width = 0.0; - float height = 0.0; - if (widget) { - QSize size = widget->sizeHint(); - width = static_cast(size.width()); - height = static_cast(size.height()); - return YGSize{ - width, - height, - }; - } - } - return YGSize{width, height}; -} +#include "core/FlexLayout/flexutils.h" bool extrautils::isNapiValueInt(Napi::Env& env, Napi::Value& num) { return env.Global() @@ -96,3 +75,13 @@ QVariant* extrautils::convertToQVariant(Napi::Env& env, Napi::Value& value) { return new QVariant(); } } + +void* extrautils::configureComponent(void* component) { return component; } +void* extrautils::configureQObject(QObject* object) { + return configureComponent(object); +} +void* extrautils::configureQWidget(QWidget* widget, YGNodeRef node, + bool isLeafNode) { + flexutils::configureFlexNode(widget, node, isLeafNode); + return configureQObject(widget); +} \ No newline at end of file diff --git a/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp b/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp index ee8b886c2..44f28e040 100644 --- a/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp +++ b/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp @@ -37,5 +37,5 @@ QObjectWrap::QObjectWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureQObject(this->getInternalInstance()); } diff --git a/src/cpp/lib/QtCore/QSize/qsize_wrap.cpp b/src/cpp/lib/QtCore/QSize/qsize_wrap.cpp index 27fa4b637..5953f0ece 100644 --- a/src/cpp/lib/QtCore/QSize/qsize_wrap.cpp +++ b/src/cpp/lib/QtCore/QSize/qsize_wrap.cpp @@ -39,7 +39,7 @@ QSizeWrap::QSizeWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureComponent(this->getInternalInstance()); } QSizeWrap::~QSizeWrap() { this->instance.reset(); } diff --git a/src/cpp/lib/QtCore/QVariant/qvariant_wrap.cpp b/src/cpp/lib/QtCore/QVariant/qvariant_wrap.cpp index 98ac85cb6..0cf4ea102 100644 --- a/src/cpp/lib/QtCore/QVariant/qvariant_wrap.cpp +++ b/src/cpp/lib/QtCore/QVariant/qvariant_wrap.cpp @@ -32,7 +32,7 @@ QVariantWrap::QVariantWrap(const Napi::CallbackInfo& info) } else { this->instance = QSharedPointer(new QVariant()); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureComponent(this->getInternalInstance()); } Napi::Value QVariantWrap::toString(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp b/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp index 4ea0360e0..e1b39aae8 100644 --- a/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp +++ b/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp @@ -41,7 +41,7 @@ QApplicationWrap::QApplicationWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureComponent(this->getInternalInstance()); } QApplicationWrap::~QApplicationWrap() { if (this->_wasManuallyCreated) { diff --git a/src/cpp/lib/QtGui/QClipboard/qclipboard_wrap.cpp b/src/cpp/lib/QtGui/QClipboard/qclipboard_wrap.cpp index 15a66971f..eeb08dd11 100644 --- a/src/cpp/lib/QtGui/QClipboard/qclipboard_wrap.cpp +++ b/src/cpp/lib/QtGui/QClipboard/qclipboard_wrap.cpp @@ -29,7 +29,7 @@ QClipboardWrap::QClipboardWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Incorrect initialization of QClipboardWrap") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureComponent(this->getInternalInstance()); } QClipboard* QClipboardWrap::getInternalInstance() { return this->instance; } diff --git a/src/cpp/lib/QtGui/QCursor/qcursor_wrap.cpp b/src/cpp/lib/QtGui/QCursor/qcursor_wrap.cpp index 6913e113f..ef6efa907 100644 --- a/src/cpp/lib/QtGui/QCursor/qcursor_wrap.cpp +++ b/src/cpp/lib/QtGui/QCursor/qcursor_wrap.cpp @@ -33,7 +33,7 @@ QCursorWrap::QCursorWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureComponent(this->getInternalInstance()); } QCursorWrap::~QCursorWrap() { this->instance.reset(); } diff --git a/src/cpp/lib/QtGui/QEvent/QKeyEvent/qkeyevent_wrap.cpp b/src/cpp/lib/QtGui/QEvent/QKeyEvent/qkeyevent_wrap.cpp index 2ccb34f3e..7329ca4e4 100644 --- a/src/cpp/lib/QtGui/QEvent/QKeyEvent/qkeyevent_wrap.cpp +++ b/src/cpp/lib/QtGui/QEvent/QKeyEvent/qkeyevent_wrap.cpp @@ -36,7 +36,7 @@ QKeyEventWrap::QKeyEventWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureComponent(this->getInternalInstance()); } QKeyEventWrap::~QKeyEventWrap() { diff --git a/src/cpp/lib/QtGui/QEvent/QMouseEvent/qmouseevent_wrap.cpp b/src/cpp/lib/QtGui/QEvent/QMouseEvent/qmouseevent_wrap.cpp index 041ff95fb..35f9f4e36 100644 --- a/src/cpp/lib/QtGui/QEvent/QMouseEvent/qmouseevent_wrap.cpp +++ b/src/cpp/lib/QtGui/QEvent/QMouseEvent/qmouseevent_wrap.cpp @@ -9,15 +9,15 @@ Napi::FunctionReference QMouseEventWrap::constructor; Napi::Object QMouseEventWrap::init(Napi::Env env, Napi::Object exports) { Napi::HandleScope scope(env); char CLASSNAME[] = "QMouseEvent"; - Napi::Function func = DefineClass( - env, CLASSNAME, - {InstanceMethod("button", &QMouseEventWrap::button), - InstanceMethod("x", &QMouseEventWrap::x), - InstanceMethod("y", &QMouseEventWrap::y), - InstanceMethod("globalX", &QMouseEventWrap::globalX), - InstanceMethod("globalY", &QMouseEventWrap::globalY), + Napi::Function func = + DefineClass(env, CLASSNAME, + {InstanceMethod("button", &QMouseEventWrap::button), + InstanceMethod("x", &QMouseEventWrap::x), + InstanceMethod("y", &QMouseEventWrap::y), + InstanceMethod("globalX", &QMouseEventWrap::globalX), + InstanceMethod("globalY", &QMouseEventWrap::globalY), - COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE}); + COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); return exports; @@ -37,7 +37,7 @@ QMouseEventWrap::QMouseEventWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureComponent(this->getInternalInstance()); } QMouseEventWrap::~QMouseEventWrap() { diff --git a/src/cpp/lib/QtGui/QIcon/qicon_wrap.cpp b/src/cpp/lib/QtGui/QIcon/qicon_wrap.cpp index ed825f647..ba253b1d9 100644 --- a/src/cpp/lib/QtGui/QIcon/qicon_wrap.cpp +++ b/src/cpp/lib/QtGui/QIcon/qicon_wrap.cpp @@ -34,7 +34,7 @@ QIconWrap::QIconWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureComponent(this->getInternalInstance()); } QIconWrap::~QIconWrap() { this->instance.reset(); } diff --git a/src/cpp/lib/QtGui/QKeySequence/qkeysequence_wrap.cpp b/src/cpp/lib/QtGui/QKeySequence/qkeysequence_wrap.cpp index bc4780504..e8937b2af 100644 --- a/src/cpp/lib/QtGui/QKeySequence/qkeysequence_wrap.cpp +++ b/src/cpp/lib/QtGui/QKeySequence/qkeysequence_wrap.cpp @@ -32,7 +32,7 @@ QKeySequenceWrap::QKeySequenceWrap(const Napi::CallbackInfo &info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureComponent(this->getInternalInstance()); } QKeySequenceWrap::~QKeySequenceWrap() { this->instance.reset(); } diff --git a/src/cpp/lib/QtGui/QPixmap/qpixmap_wrap.cpp b/src/cpp/lib/QtGui/QPixmap/qpixmap_wrap.cpp index 19452c098..39ba0d928 100644 --- a/src/cpp/lib/QtGui/QPixmap/qpixmap_wrap.cpp +++ b/src/cpp/lib/QtGui/QPixmap/qpixmap_wrap.cpp @@ -41,7 +41,7 @@ QPixmapWrap::QPixmapWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureComponent(this->getInternalInstance()); } QPixmapWrap::~QPixmapWrap() { this->instance.reset(); } diff --git a/src/cpp/lib/QtWidgets/QAction/qaction_wrap.cpp b/src/cpp/lib/QtWidgets/QAction/qaction_wrap.cpp index a6b5457fd..578d56363 100644 --- a/src/cpp/lib/QtWidgets/QAction/qaction_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QAction/qaction_wrap.cpp @@ -50,7 +50,7 @@ QActionWrap::QActionWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureQObject(this->getInternalInstance()); } QActionWrap::~QActionWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QCheckBox/qcheckbox_wrap.cpp b/src/cpp/lib/QtWidgets/QCheckBox/qcheckbox_wrap.cpp index 4b1cdc9df..f6ed50edd 100644 --- a/src/cpp/lib/QtWidgets/QCheckBox/qcheckbox_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QCheckBox/qcheckbox_wrap.cpp @@ -39,11 +39,9 @@ QCheckBoxWrap::QCheckBoxWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); - // Adds measure function on yoga node so that widget size is calculated based - // on its text also. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); } QCheckBoxWrap::~QCheckBoxWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QDial/qdial_wrap.cpp b/src/cpp/lib/QtWidgets/QDial/qdial_wrap.cpp index 113b4c5e5..e6bfa4d15 100644 --- a/src/cpp/lib/QtWidgets/QDial/qdial_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QDial/qdial_wrap.cpp @@ -43,11 +43,10 @@ QDialWrap::QDialWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); - // Adds measure function on yoga node so that widget size is calculated based - // on its own size. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); } QDialWrap::~QDialWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QGridLayout/qgridlayout_wrap.cpp b/src/cpp/lib/QtWidgets/QGridLayout/qgridlayout_wrap.cpp index a972b11a4..1da7e40e0 100644 --- a/src/cpp/lib/QtWidgets/QGridLayout/qgridlayout_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QGridLayout/qgridlayout_wrap.cpp @@ -37,7 +37,7 @@ QGridLayoutWrap::QGridLayoutWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureQObject(this->getInternalInstance()); } Napi::Value QGridLayoutWrap::addWidget(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp b/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp index f6ae331b3..8dbb0ca3e 100644 --- a/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp @@ -45,11 +45,10 @@ QLabelWrap::QLabelWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); - // Adds measure function on yoga node so that widget size is calculated based - // on its text also. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + auto flexNode = this->getInternalInstance()->getFlexNode(); + YGNodeSetNodeType(flexNode, YGNodeType::YGNodeTypeText); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), flexNode, true); } Napi::Value QLabelWrap::setWordWrap(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QLineEdit/qlineedit_wrap.cpp b/src/cpp/lib/QtWidgets/QLineEdit/qlineedit_wrap.cpp index 3107ade6e..2083e344a 100644 --- a/src/cpp/lib/QtWidgets/QLineEdit/qlineedit_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QLineEdit/qlineedit_wrap.cpp @@ -43,11 +43,9 @@ QLineEditWrap::QLineEditWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); - // Adds measure function on yoga node so that widget size is calculated based - // on its text also. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); } QLineEditWrap::~QLineEditWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QMainWindow/qmainwindow_wrap.cpp b/src/cpp/lib/QtWidgets/QMainWindow/qmainwindow_wrap.cpp index 07e315e60..bd4bf5a89 100644 --- a/src/cpp/lib/QtWidgets/QMainWindow/qmainwindow_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QMainWindow/qmainwindow_wrap.cpp @@ -46,7 +46,8 @@ QMainWindowWrap::QMainWindowWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode()); } Napi::Value QMainWindowWrap::setCentralWidget(const Napi::CallbackInfo& info) { @@ -54,16 +55,13 @@ Napi::Value QMainWindowWrap::setCentralWidget(const Napi::CallbackInfo& info) { Napi::HandleScope scope(env); Napi::Object widgetObject = info[0].As(); + Napi::External centralWidgetFlexNode = + info[1].As>(); QWidgetWrap* centralWidget = Napi::ObjectWrap::Unwrap(widgetObject); - - Napi::External flexNodeObject = info[1].As>(); - YGNodeRef flexNodeRef = flexNodeObject.Data(); - - YGNodeRef node = this->instance->getFlexNode(); - YGNodeInsertChild(node, flexNodeRef, 0); + YGNodeInsertChild(this->instance->getFlexNode(), centralWidgetFlexNode.Data(), + 0); this->instance->setCentralWidget(centralWidget->getInternalInstance()); - return env.Null(); } diff --git a/src/cpp/lib/QtWidgets/QMenu/qmenu_wrap.cpp b/src/cpp/lib/QtWidgets/QMenu/qmenu_wrap.cpp index 031f7d467..b3391c3bb 100644 --- a/src/cpp/lib/QtWidgets/QMenu/qmenu_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QMenu/qmenu_wrap.cpp @@ -40,11 +40,9 @@ QMenuWrap::QMenuWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); - // Adds measure function on yoga node so that widget size is calculated based - // on its text also. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); } QMenuWrap::~QMenuWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QMenuBar/qmenubar_wrap.cpp b/src/cpp/lib/QtWidgets/QMenuBar/qmenubar_wrap.cpp index a5628730d..534deea1e 100644 --- a/src/cpp/lib/QtWidgets/QMenuBar/qmenubar_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QMenuBar/qmenubar_wrap.cpp @@ -45,11 +45,8 @@ QMenuBarWrap::QMenuBarWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); - // Adds measure function on yoga node so that widget size is calculated based - // on its text also. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode()); } QMenuBarWrap::~QMenuBarWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QPlainTextEdit/qplaintextedit_wrap.cpp b/src/cpp/lib/QtWidgets/QPlainTextEdit/qplaintextedit_wrap.cpp index b8eeabfc7..9ea2b7f56 100644 --- a/src/cpp/lib/QtWidgets/QPlainTextEdit/qplaintextedit_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QPlainTextEdit/qplaintextedit_wrap.cpp @@ -52,11 +52,9 @@ QPlainTextEditWrap::QPlainTextEditWrap(const Napi::CallbackInfo &info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); - // Adds measure function on yoga node so that widget size is calculated based - // on its text also. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); } QPlainTextEditWrap::~QPlainTextEditWrap() { diff --git a/src/cpp/lib/QtWidgets/QProgressBar/qprogressbar_wrap.cpp b/src/cpp/lib/QtWidgets/QProgressBar/qprogressbar_wrap.cpp index 9178a4e8d..3cffcc84e 100644 --- a/src/cpp/lib/QtWidgets/QProgressBar/qprogressbar_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QProgressBar/qprogressbar_wrap.cpp @@ -42,11 +42,9 @@ QProgressBarWrap::QProgressBarWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); - // Adds measure function on yoga node so that widget size is calculated based - // on its own size. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); } QProgressBarWrap::~QProgressBarWrap() { diff --git a/src/cpp/lib/QtWidgets/QPushButton/qpushbutton_wrap.cpp b/src/cpp/lib/QtWidgets/QPushButton/qpushbutton_wrap.cpp index 27f0b0426..d978097cb 100644 --- a/src/cpp/lib/QtWidgets/QPushButton/qpushbutton_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QPushButton/qpushbutton_wrap.cpp @@ -38,10 +38,9 @@ QPushButtonWrap::QPushButtonWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - // Adds measure function on yoga node so that widget size is calculated based - // on its text also. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); } QPushButtonWrap::~QPushButtonWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QRadioButton/qradiobutton_wrap.cpp b/src/cpp/lib/QtWidgets/QRadioButton/qradiobutton_wrap.cpp index ef3b10560..238df8486 100644 --- a/src/cpp/lib/QtWidgets/QRadioButton/qradiobutton_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QRadioButton/qradiobutton_wrap.cpp @@ -38,11 +38,9 @@ QRadioButtonWrap::QRadioButtonWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); - // Adds measure function on yoga node so that widget size is calculated based - // on its own size. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); } QRadioButtonWrap::~QRadioButtonWrap() { diff --git a/src/cpp/lib/QtWidgets/QScrollArea/qscrollarea_wrap.cpp b/src/cpp/lib/QtWidgets/QScrollArea/qscrollarea_wrap.cpp index dcc42e3c4..f26f6ff4a 100644 --- a/src/cpp/lib/QtWidgets/QScrollArea/qscrollarea_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QScrollArea/qscrollarea_wrap.cpp @@ -40,11 +40,14 @@ QScrollAreaWrap::QScrollAreaWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); - // Adds measure function on yoga node so that widget size is calculated based - // on its own size. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + this->scrollNode = YGNodeNew(); + YGConfigSetUseWebDefaults(this->scrollNode->getConfig(), true); + FlexNodeContext* scrollNodeCtx = new FlexNodeContext(this->instance); + YGNodeSetContext(this->scrollNode, scrollNodeCtx); + + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); } QScrollAreaWrap::~QScrollAreaWrap() { extrautils::safeDelete(this->instance); } @@ -53,8 +56,11 @@ Napi::Value QScrollAreaWrap::setWidget(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Object contentWidget = info[0].As(); + Napi::External centralWidgetFlexNode = + info[1].As>(); QWidgetWrap* contentWidgetWrap = Napi::ObjectWrap::Unwrap(contentWidget); + YGNodeInsertChild(this->scrollNode, centralWidgetFlexNode.Data(), 0); this->instance->setWidget(contentWidgetWrap->getInternalInstance()); return env.Null(); } diff --git a/src/cpp/lib/QtWidgets/QShortcut/qshortcut_wrap.cpp b/src/cpp/lib/QtWidgets/QShortcut/qshortcut_wrap.cpp index 567a907ca..0ace6435e 100644 --- a/src/cpp/lib/QtWidgets/QShortcut/qshortcut_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QShortcut/qshortcut_wrap.cpp @@ -40,7 +40,7 @@ QShortcutWrap::QShortcutWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureQObject(this->getInternalInstance()); } QShortcutWrap::~QShortcutWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QSpinBox/qspinbox_wrap.cpp b/src/cpp/lib/QtWidgets/QSpinBox/qspinbox_wrap.cpp index 8f0d90159..e46469f5b 100644 --- a/src/cpp/lib/QtWidgets/QSpinBox/qspinbox_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QSpinBox/qspinbox_wrap.cpp @@ -45,11 +45,9 @@ QSpinBoxWrap::QSpinBoxWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); - // Adds measure function on yoga node so that widget size is calculated based - // on its text also. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); } QSpinBoxWrap::~QSpinBoxWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.cpp b/src/cpp/lib/QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.cpp index b4aa7648d..0ce41d393 100644 --- a/src/cpp/lib/QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.cpp @@ -48,7 +48,7 @@ QSystemTrayIconWrap::QSystemTrayIconWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureQObject(this->getInternalInstance()); } QSystemTrayIconWrap::~QSystemTrayIconWrap() { diff --git a/src/cpp/lib/QtWidgets/QTabWidget/qtabwidget_wrap.cpp b/src/cpp/lib/QtWidgets/QTabWidget/qtabwidget_wrap.cpp index ade086838..d4f4b4f61 100644 --- a/src/cpp/lib/QtWidgets/QTabWidget/qtabwidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTabWidget/qtabwidget_wrap.cpp @@ -47,11 +47,9 @@ QTabWidgetWrap::QTabWidgetWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); - // Adds measure function on yoga node so that widget size is calculated based - // on its text also. - YGNodeSetMeasureFunc(this->instance->getFlexNode(), - &extrautils::measureQtWidget); + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + true); } Napi::Value QTabWidgetWrap::addTab(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp b/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp index 5be778a33..33c822dc7 100644 --- a/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp @@ -39,5 +39,7 @@ QWidgetWrap::QWidgetWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureQWidget( + this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), + false); } diff --git a/src/cpp/lib/core/FlexLayout/flexitem.cpp b/src/cpp/lib/core/FlexLayout/flexitem.cpp index b4a749ccc..eb3644eb5 100644 --- a/src/cpp/lib/core/FlexLayout/flexitem.cpp +++ b/src/cpp/lib/core/FlexLayout/flexitem.cpp @@ -1,10 +1,20 @@ #include "core/FlexLayout/flexitem.h" +#include + +#include "core/FlexLayout/flexutils.h" + FlexItem::FlexItem() { this->node = YGNodeNew(); - // YGConfigSetUseWebDefaults(this->node->getConfig(),true); + YGConfigSetUseWebDefaults(this->node->getConfig(), true); } YGNodeRef FlexItem::getFlexNode() const { return this->node; } -FlexItem::~FlexItem() { YGNodeFree(this->node); } +FlexItem::~FlexItem() { + FlexNodeContext* ctx = flexutils::getFlexNodeContext(this->node); + if (ctx != nullptr) { + delete ctx; + }; + YGNodeFree(this->node); +} diff --git a/src/cpp/lib/core/FlexLayout/flexlayout.cpp b/src/cpp/lib/core/FlexLayout/flexlayout.cpp index 151e20420..73c2a182a 100644 --- a/src/cpp/lib/core/FlexLayout/flexlayout.cpp +++ b/src/cpp/lib/core/FlexLayout/flexlayout.cpp @@ -1,19 +1,11 @@ #include "core/FlexLayout/flexlayout.h" +#include #include +#include "core/FlexLayout/flexitem.h" +#include "core/FlexLayout/flexutils.h" #include "core/YogaWidget/yogawidget.h" -#include "spdlog/spdlog.h" - -FlexLayout::NodeContext* FlexLayout::getNodeContext(YGNodeRef node) { - if (!node) { - return nullptr; - } - void* childContext = YGNodeGetContext(node); - NodeContext* ctx = static_cast( - childContext); // because we are managing this at all times - return ctx; -} FlexLayout::FlexLayout(QWidget* parentWidget, YGNodeRef parentNode) : QLayout(parentWidget) { @@ -27,99 +19,44 @@ FlexLayout::~FlexLayout() { const uint32_t childCount = YGNodeGetChildCount(this->node); for (uint32_t i = 0; i < childCount; i++) { const YGNodeRef oldChild = YGNodeGetChild(this->node, i); - NodeContext* ctx = getNodeContext(oldChild); - if (ctx) { - delete ctx->item; + FlexNodeContext* childCtx = flexutils::getFlexNodeContext(oldChild); + + if (childCtx->layoutItem()) { + delete childCtx->layoutItem(); + childCtx->setLayoutItem(nullptr); } } YGNodeRemoveAllChildren(this->node); } -QSize FlexLayout::sizeHint() const { - if (!this->node) { - return QSize(0, 0); - } - int width = static_cast(YGNodeLayoutGetWidth(this->node)); - int height = static_cast(YGNodeLayoutGetHeight(this->node)); - return QSize(width, height); -} - void FlexLayout::addItem(QLayoutItem* item) { // Noop: We already have addWidget doing all the hard work. -} - -QLayoutItem* FlexLayout::itemAt(int index) const { - if (!this->node) { - return nullptr; - } - // spdlog::info("flexlayout: itemAt {}",index); - YGNodeRef childNode = YGNodeGetChild(this->node, static_cast(index)); - NodeContext* ctx = getNodeContext(childNode); - if (!ctx) { - return nullptr; - } - return ctx->item; -} - -QLayoutItem* FlexLayout::takeAt(int index) { - YGNodeRef childNode = YGNodeGetChild(this->node, static_cast(index)); - NodeContext* ctx = getNodeContext(childNode); - QLayoutItem* childLayoutItem = ctx->item; - YGNodeRemoveChild(this->node, childNode); - spdlog::info("flexlayout: takeAt ", index); - delete ctx; - return childLayoutItem; -} - -int FlexLayout::count() const { - if (!this->node) { - return 0; - } - float childCount = YGNodeGetChildCount(this->node); - spdlog::info("flexlayout: count {}", childCount); - return static_cast(childCount); + return; } void FlexLayout::addWidget(QWidget* childWidget, YGNodeRef childNode) { if (!this->node) { - spdlog::warn( - "Flex layout's parent yoga node not set yet. Set it using setFlexNode. " - "Child widget will not be added to Flex Layout"); + qWarning() << "Flex layout's parent yoga node not set yet. Set it using " + "setFlexNode. \n" + << "Child widget will not be added to Flex Layout"; return; } uint count = YGNodeGetChildCount(this->node); YGNodeInsertChild(this->node, childNode, count); - QLayoutItem* layoutItem = new QWidgetItem(childWidget); - NodeContext* childContext = new NodeContext(layoutItem); - YGNodeSetContext(childNode, static_cast(childContext)); + FlexNodeContext* childCtx = flexutils::getFlexNodeContext(childNode); + auto layoutitem = new QWidgetItem(childWidget); + childCtx->setLayoutItem(layoutitem); QLayout::addWidget(childWidget); this->invalidate(); } -void FlexLayout::removeWidget(QWidget* childWidget, YGNodeRef childNode) { - if (!this->node) { - spdlog::warn( - "Flex layout's parent yoga node not set yet. Set it using setFlexNode. " - "childwidget cant be removed"); - return; - } - - NodeContext* ctx = getNodeContext(childNode); - if (ctx) { - delete ctx->item; - } - YGNodeRemoveChild(this->node, childNode); - QLayout::removeWidget(childWidget); - this->invalidate(); -} - void FlexLayout::insertChildBefore(QWidget* childWidget, YGNodeRef beforeChildNode, YGNodeRef childNode) { if (!this->node) { - spdlog::warn( - "Flex layout's parent yoga node not set yet. Set it using setFlexNode. " - "childwidget cant be inserted"); + qWarning() << "Flex layout's parent yoga node not set yet. Set it using " + "setFlexNode. \n" + << "childwidget cant be inserted"; return; } uint count = YGNodeGetChildCount(this->node); @@ -131,14 +68,61 @@ void FlexLayout::insertChildBefore(QWidget* childWidget, } } YGNodeInsertChild(this->node, childNode, indexToInsert); - QLayoutItem* layoutItem = new QWidgetItem(childWidget); - NodeContext* childContext = new NodeContext(layoutItem); - YGNodeSetContext(childNode, static_cast(childContext)); + FlexNodeContext* ctx = flexutils::getFlexNodeContext(childNode); + ctx->setLayoutItem(new QWidgetItem(childWidget)); QLayout::addWidget(childWidget); this->invalidate(); } -YGNodeRef FlexLayout::getRootNode(YGNodeRef node) { +QLayoutItem* FlexLayout::itemAt(int index) const { + if (!this->node || + index >= static_cast(YGNodeGetChildCount(this->node))) { + return nullptr; + } + YGNodeRef childNode = YGNodeGetChild(this->node, static_cast(index)); + FlexNodeContext* childCtx = flexutils::getFlexNodeContext(childNode); + return childCtx->layoutItem(); +} + +QLayoutItem* FlexLayout::takeAt(int index) { + if (!this->node || + index >= static_cast(YGNodeGetChildCount(this->node))) { + return nullptr; + } + YGNodeRef childNode = YGNodeGetChild(this->node, static_cast(index)); + FlexNodeContext* ctx = flexutils::getFlexNodeContext(childNode); + QLayoutItem* childLayoutItem = ctx->layoutItem(); + ctx->setLayoutItem(nullptr); + YGNodeRemoveChild(this->node, childNode); + return childLayoutItem; +} + +int FlexLayout::count() const { + if (!this->node) { + return 0; + } + float childCount = YGNodeGetChildCount(this->node); + return static_cast(childCount); +} + +void FlexLayout::removeWidget(QWidget* childWidget, YGNodeRef childNode) { + if (!this->node) { + qWarning() << "Flex layout's parent yoga node not set yet. Set it using " + "setFlexNode. " + << "childwidget cant be removed"; + return; + } + FlexNodeContext* ctx = flexutils::getFlexNodeContext(childNode); + if (ctx->layoutItem()) { + delete ctx->layoutItem(); + ctx->setLayoutItem(nullptr); + } + YGNodeRemoveChild(this->node, childNode); + QLayout::removeWidget(childWidget); + this->invalidate(); +} + +YGNodeRef FlexLayout::getRootNode(YGNodeRef node) const { YGNodeRef parent = node->getOwner(); if (!parent) { return node; @@ -147,35 +131,37 @@ YGNodeRef FlexLayout::getRootNode(YGNodeRef node) { } } +QSize FlexLayout::sizeHint() const { + QSize totalSize; + YGNodeRef parentNode = this->node; + YGNodeRef rootNode = getRootNode(parentNode); + YGDirection rootDirection = YGNodeStyleGetDirection(rootNode); + YGNodeStyleSetMaxHeight(rootNode, QWIDGETSIZE_MAX); + YGNodeStyleSetMaxWidth(rootNode, QWIDGETSIZE_MAX); + YGNodeCalculateLayout(rootNode, 0, 0, rootDirection); + totalSize.rwidth() = YGNodeLayoutGetWidth(this->node); + totalSize.rheight() = YGNodeLayoutGetHeight(this->node); + return totalSize; +} + void FlexLayout::setGeometry(const QRect& rect) { if (!this->node) { return; } - YGNodeRef rootNode = getRootNode(this->node); - QWidget* parentWidget = this->parentWidget(); - QWidget* window = parentWidget->window(); + YGNodeRef rootNode = FlexLayout::getRootNode(this->node); YGDirection direction = YGNodeStyleGetDirection(rootNode); - YGNodeCalculateLayout(rootNode, window->width(), window->height(), direction); + YGNodeStyleSetMaxHeight(rootNode, QWIDGETSIZE_MAX); + YGNodeStyleSetMaxWidth(rootNode, QWIDGETSIZE_MAX); + YGNodeCalculateLayout(rootNode, 0, 0, direction); + uint count = YGNodeGetChildCount(this->node); for (uint i = 0; i < count; ++i) { YGNode* childNode = YGNodeGetChild(this->node, i); - int width = static_cast(YGNodeLayoutGetWidth(childNode)); - int height = static_cast(YGNodeLayoutGetHeight(childNode)); - int left = static_cast(YGNodeLayoutGetLeft(childNode)); - int top = static_cast(YGNodeLayoutGetTop(childNode)); - - QRect childRect(left, top, width, height); - NodeContext* ctx = getNodeContext(childNode); - if (ctx) { - QLayoutItem* childLayoutItem = ctx->item; - QWidget* childWidget = childLayoutItem->widget(); - if (childWidget) { - childWidget->setGeometry(childRect); - } else { - childLayoutItem->setGeometry(childRect); - } - } + QRect childRect = flexutils::getFlexNodeGeometry(childNode); + FlexNodeContext* ctx = flexutils::getFlexNodeContext(childNode); + QLayoutItem* childItem = ctx->layoutItem(); + childItem->setGeometry(childRect); } QLayout::setGeometry(rect); } diff --git a/src/cpp/lib/core/FlexLayout/flexlayout_wrap.cpp b/src/cpp/lib/core/FlexLayout/flexlayout_wrap.cpp index 2e9df2c01..6f50c8d5d 100644 --- a/src/cpp/lib/core/FlexLayout/flexlayout_wrap.cpp +++ b/src/cpp/lib/core/FlexLayout/flexlayout_wrap.cpp @@ -41,7 +41,7 @@ FlexLayoutWrap::FlexLayoutWrap(const Napi::CallbackInfo& info) Napi::TypeError::New(env, "Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = this->getInternalInstance(); + this->rawData = extrautils::configureQObject(this->getInternalInstance()); } Napi::Value FlexLayoutWrap::addWidget(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/core/FlexLayout/flexutils.cpp b/src/cpp/lib/core/FlexLayout/flexutils.cpp new file mode 100644 index 000000000..a02971b6d --- /dev/null +++ b/src/cpp/lib/core/FlexLayout/flexutils.cpp @@ -0,0 +1,70 @@ +#include "core/FlexLayout/flexutils.h" + +FlexNodeContext::FlexNodeContext(void* widget) { + this->_widget = widget; + this->_layoutItem = nullptr; +} + +QWidget* FlexNodeContext::widget() { + QWidget* flexNodeWidget = static_cast(this->_widget); + return flexNodeWidget; +} + +QLayoutItem* FlexNodeContext::layoutItem() { return this->_layoutItem; } + +void FlexNodeContext::setLayoutItem(QLayoutItem* item) { + this->_layoutItem = item; +} + +const QRect flexutils::getFlexNodeGeometry(YGNodeRef node) { + int width = static_cast(YGNodeLayoutGetWidth(node)); + int height = static_cast(YGNodeLayoutGetHeight(node)); + int left = static_cast(YGNodeLayoutGetLeft(node)); + int top = static_cast(YGNodeLayoutGetTop(node)); + const QRect geometry(left, top, width, height); + return geometry; +} + +void flexutils::setFlexNodeGeometry(YGNodeRef node, const QRect& geometry) { + int width = geometry.width(); + int height = geometry.height(); + int left = geometry.left(); + int top = geometry.top(); + + YGNodeStyleSetWidth(node, width); + YGNodeStyleSetHeight(node, height); + YGNodeStyleSetPosition(node, YGEdgeTop, top); + YGNodeStyleSetPosition(node, YGEdgeLeft, left); +} + +FlexNodeContext* flexutils::getFlexNodeContext(YGNodeRef node) { + if (!node) { + return nullptr; + } + void* rawCtx = YGNodeGetContext(node); + FlexNodeContext* ctx = static_cast(rawCtx); + return ctx; +} + +YGSize flexutils::measureQtWidget(YGNodeRef node, float _width, + YGMeasureMode widthMode, float _height, + YGMeasureMode heightMode) { + FlexNodeContext* ctx = getFlexNodeContext(node); + QWidget* widget = ctx->widget(); + QSize size = widget->sizeHint(); + float width = static_cast(size.width()); + float height = static_cast(size.height()); + return YGSize{ + width, + height, + }; +} + +void flexutils::configureFlexNode(QWidget* widget, YGNodeRef node, + bool isLeafNode) { + FlexNodeContext* ctx = new FlexNodeContext(widget); + YGNodeSetContext(node, ctx); + if (isLeafNode) { + YGNodeSetMeasureFunc(node, &flexutils::measureQtWidget); + } +} \ No newline at end of file diff --git a/src/demo.ts b/src/demo.ts index 6cf52c786..484613768 100644 --- a/src/demo.ts +++ b/src/demo.ts @@ -1,44 +1,51 @@ -import { QMainWindow } from './index'; -import { QWidget } from './lib/QtWidgets/QWidget'; -import { FlexLayout } from './lib/core/FlexLayout'; -import { QLabel, QLabelEvents } from './lib/QtWidgets/QLabel'; -import { AlignmentFlag } from './lib/QtEnums'; -import { QPixmap } from './lib/QtGui/QPixmap'; -import { QMouseEvent } from './lib/QtGui/QEvent/QMouseEvent'; +import { QWidget, QScrollArea, QMainWindow, FlexLayout, QLabel } from './index'; -const win = new QMainWindow(); -const view = new QWidget(); -view.setLayout(new FlexLayout()); -view.setStyleSheet(` - flex: 1; - width: '100%'; - height: '100%'; -`); -const hello = new QLabel(); -hello.setText('Hello'); -hello.setStyleSheet(` - border: 1px solid blue; -`); -const world = new QLabel(); -world.setText('World'); -world.addEventListener(QLabelEvents.MouseButtonPress, e => { - const event = new QMouseEvent(e); - console.log('clicked!', event.x(), event.y()); -}); -world.setStyleSheet(` - border: 1px solid blue; - qproperty-alignment: AlignCenter; -`); -const pixmap = new QPixmap('/Users/atulr/Project/nodegui/nodegui/extras/assets/kitchen.png'); -hello.setProperty('pixmap', pixmap); +const main = async (): Promise => { + const win = new QMainWindow(); + const scrollArea = new QScrollArea(); + const center = new QWidget(); + const label = new QLabel(); + label.setText(` + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + Hellloooooo + `); -hello.setProperty('alignment', AlignmentFlag.AlignCenter); + await scrollArea.setInlineStyle('border: 1px solid yellow;'); + await center.setInlineStyle(`border: 3px solid blue;`); + await label.setInlineStyle(`border: 2px solid green;padding: 10;`); -if (view.layout) { - view.layout.addWidget(hello); - view.layout.addWidget(world); -} -win.setCentralWidget(view); -win.show(); + center.setLayout(new FlexLayout()); + center.layout?.addWidget(label); + scrollArea.setWidget(center); + win.setCentralWidget(scrollArea); + win.show(); + (global as any).win = win; +}; -(global as any).win = win; // To prevent win from being garbage collected. +main(); diff --git a/src/lib/QtGui/QEvent/QKeyEvent.ts b/src/lib/QtGui/QEvent/QKeyEvent.ts index 1d9c3ddea..ee7c39961 100644 --- a/src/lib/QtGui/QEvent/QKeyEvent.ts +++ b/src/lib/QtGui/QEvent/QKeyEvent.ts @@ -7,19 +7,19 @@ export class QKeyEvent { constructor(event: NativeEvent) { this.native = new addon.QKeyEvent(event); } - text = (): string => { + text(): string { return this.native.text(); - }; - key = (): number => { + } + key(): number { return this.native.key(); - }; - modifiers = (): number => { + } + modifiers(): number { return this.native.modifiers(); - }; - count = (): number => { + } + count(): number { return this.native.count(); - }; - isAutoRepeat = (): boolean => { + } + isAutoRepeat(): boolean { return this.native.isAutoRepeat(); - }; + } } diff --git a/src/lib/QtGui/QEvent/QMouseEvent.ts b/src/lib/QtGui/QEvent/QMouseEvent.ts index 53c5997d5..46d7fdc31 100644 --- a/src/lib/QtGui/QEvent/QMouseEvent.ts +++ b/src/lib/QtGui/QEvent/QMouseEvent.ts @@ -7,19 +7,19 @@ export class QMouseEvent { constructor(event: NativeEvent) { this.native = new addon.QMouseEvent(event); } - button = (): string => { + button(): string { return this.native.button(); - }; - x = (): number => { + } + x(): number { return this.native.x(); - }; - y = (): number => { + } + y(): number { return this.native.y(); - }; - globalX = (): number => { + } + globalX(): number { return this.native.globalX(); - }; - globalY = (): number => { + } + globalY(): number { return this.native.globalY(); - }; + } } diff --git a/src/lib/QtGui/QIcon.ts b/src/lib/QtGui/QIcon.ts index db06f3e88..0d2ab8e6c 100644 --- a/src/lib/QtGui/QIcon.ts +++ b/src/lib/QtGui/QIcon.ts @@ -25,7 +25,7 @@ export class QIcon extends Component { this.native = new addon.QIcon(); } } - pixmap = (width: number, height: number, mode?: QIconMode, state?: QIconState): QPixmap => { + pixmap(width: number, height: number, mode?: QIconMode, state?: QIconState): QPixmap { let nativePixmap; if (mode && state) { nativePixmap = this.native.pixmap(width, height, mode, state); @@ -35,12 +35,10 @@ export class QIcon extends Component { nativePixmap = this.native.pixmap(width, height); } return new QPixmap(nativePixmap); - }; - + } isMask(): boolean { return this.native.isMask(); } - setIsMask(isMask: boolean): void { this.native.setIsMask(isMask); } diff --git a/src/lib/QtWidgets/QLayout.ts b/src/lib/QtWidgets/QLayout.ts index bc982eec7..ab5a357df 100644 --- a/src/lib/QtWidgets/QLayout.ts +++ b/src/lib/QtWidgets/QLayout.ts @@ -5,9 +5,9 @@ import { NodeObject } from '../QtCore/QObject'; export abstract class NodeLayout extends NodeObject { type = 'layout'; abstract addWidget(childWidget: NodeWidget, ...args: any[]): void; - activate = (): boolean => { + activate(): boolean { return this.native.activate(); - }; + } invalidate(): void { this.native.invalidate(); } diff --git a/src/lib/QtWidgets/QScrollArea.ts b/src/lib/QtWidgets/QScrollArea.ts index 35d3f6679..bcea04322 100644 --- a/src/lib/QtWidgets/QScrollArea.ts +++ b/src/lib/QtWidgets/QScrollArea.ts @@ -24,7 +24,7 @@ export class QScrollArea extends QAbstractScrollArea { setWidget(widget: NodeWidget): void { // react:✓, //TODO:getter this.contentWidget = widget; - this.native.setWidget(widget.native); + this.native.setWidget(widget.native, widget.getFlexNode()); } takeWidget(): NodeWidget | null { // react:✓ diff --git a/src/lib/QtWidgets/QWidget.ts b/src/lib/QtWidgets/QWidget.ts index bac276cac..2e6d7277b 100644 --- a/src/lib/QtWidgets/QWidget.ts +++ b/src/lib/QtWidgets/QWidget.ts @@ -126,13 +126,16 @@ export abstract class NodeWidget extends YogaWidget { } setLayout(parentLayout: NodeLayout): void { const flexLayout = parentLayout as FlexLayout; + this.native.setLayout(parentLayout.native); if (flexLayout.setFlexNode) { //if flex layout set the flexnode flexLayout.setFlexNode(this.getFlexNode()); } - this.native.setLayout(parentLayout.native); this.layout = parentLayout; } + adjustSize(): void { + this.native.adjustSize(); + } } type Rect = { diff --git a/src/lib/core/Style/StyleSheet.ts b/src/lib/core/Style/StyleSheet.ts index 24112e7af..30a038b18 100644 --- a/src/lib/core/Style/StyleSheet.ts +++ b/src/lib/core/Style/StyleSheet.ts @@ -3,7 +3,7 @@ import cuid from 'cuid'; import nodeguiAutoPrefixer from 'postcss-nodegui-autoprefixer'; import { NodeWidget } from '../../QtWidgets/QWidget'; export class StyleSheet { - static create = async (cssString: string): Promise => { + static async create(cssString: string): Promise { const { css } = await postcss([nodeguiAutoPrefixer()]) .process(cssString, { from: undefined }) .catch(err => { @@ -11,7 +11,7 @@ export class StyleSheet { return { css: cssString }; }); return css; - }; + } } export async function prepareInlineStyleSheet(widget: NodeWidget, rawStyle: string): Promise { diff --git a/src/lib/core/YogaWidget.ts b/src/lib/core/YogaWidget.ts index 27fc2c962..a9baa077b 100644 --- a/src/lib/core/YogaWidget.ts +++ b/src/lib/core/YogaWidget.ts @@ -2,7 +2,7 @@ import { NodeObject } from '../QtCore/QObject'; export type FlexNode = {}; export abstract class YogaWidget extends NodeObject { - getFlexNode = (): FlexNode => { + getFlexNode(): FlexNode { return this.native.getFlexNode(); - }; + } } diff --git a/website/docs/development/common_errors.md b/website/docs/development/common_errors.md index 2489f57aa..377b5e2f4 100644 --- a/website/docs/development/common_errors.md +++ b/website/docs/development/common_errors.md @@ -3,5 +3,5 @@ 1. **Segmentation fault:** Segmentation fault occurs when you access a Pointer that is pointing to an invalid memory address. One major reason for this can be that JS garbage collector would have garbage collected the addon generated value and you try accessing it after a while. This is mostly the case if you see seg fault happening randomly after some time of startup. 2. **Widget not visible in Flex layout** Widget might have gotten zero height/width. This can occur if yoga was not able to get the default height/width of the widget. Make sure you have implemented - `YGNodeSetMeasureFunc(this->instance->getFlexNode(), &extrautils::measureQtWidget);` + `YGNodeSetMeasureFunc(this->instance->getFlexNode(), &flexutils::measureQtWidget);` if its a leaf node widget(doesnt contain any children).