From e0dad876ece396986e5211388b3ade9261820298 Mon Sep 17 00:00:00 2001 From: mspencer92 Date: Tue, 24 Mar 2020 15:31:50 -0400 Subject: [PATCH] Added more functions for QTreeWidget and QTreeWidgetItem and added a function to sort and filter QTreeWidget (#465) --- .../QtWidgets/QTreeWidget/qtreewidget_wrap.h | 1 + .../QTreeWidgetItem/qtreewidgetitem_wrap.h | 2 + .../QTreeWidget/qtreewidget_wrap.cpp | 22 ++++++ .../QTreeWidgetItem/qtreewidgetitem_wrap.cpp | 21 +++++- src/demo.ts | 69 +++++++++++++------ src/lib/QtWidgets/QTreeWidget.ts | 16 +++++ src/lib/QtWidgets/QTreeWidgetItem.ts | 8 +++ 7 files changed, 118 insertions(+), 21 deletions(-) diff --git a/src/cpp/include/nodegui/QtWidgets/QTreeWidget/qtreewidget_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTreeWidget/qtreewidget_wrap.h index 37cfe5942..3e626444e 100644 --- a/src/cpp/include/nodegui/QtWidgets/QTreeWidget/qtreewidget_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QTreeWidget/qtreewidget_wrap.h @@ -35,6 +35,7 @@ class DLL_EXPORT QTreeWidgetWrap : public Napi::ObjectWrap { Napi::Value setHeaderLabels(const Napi::CallbackInfo &info); Napi::Value setItemWidget(const Napi::CallbackInfo &info); Napi::Value currentItem(const Napi::CallbackInfo &info); + Napi::Value findItems(const Napi::CallbackInfo& info); // Napi::Value addTopLevelItems(const Napi::CallbackInfo& info); // Napi::Value setHorizontalScrollBarPolicy(const Napi::CallbackInfo& info); diff --git a/src/cpp/include/nodegui/QtWidgets/QTreeWidgetItem/qtreewidgetitem_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTreeWidgetItem/qtreewidgetitem_wrap.h index 50db3433b..549f8a83f 100644 --- a/src/cpp/include/nodegui/QtWidgets/QTreeWidgetItem/qtreewidgetitem_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QTreeWidgetItem/qtreewidgetitem_wrap.h @@ -41,4 +41,6 @@ class DLL_EXPORT QTreeWidgetItemWrap Napi::Value flags(const Napi::CallbackInfo &info); Napi::Value setData(const Napi::CallbackInfo &info); Napi::Value data(const Napi::CallbackInfo &info); + Napi::Value isHidden(const Napi::CallbackInfo &info); + Napi::Value setHidden(const Napi::CallbackInfo &info); }; \ No newline at end of file diff --git a/src/cpp/lib/QtWidgets/QTreeWidget/qtreewidget_wrap.cpp b/src/cpp/lib/QtWidgets/QTreeWidget/qtreewidget_wrap.cpp index b65c2ef0f..1c901941e 100644 --- a/src/cpp/lib/QtWidgets/QTreeWidget/qtreewidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTreeWidget/qtreewidget_wrap.cpp @@ -25,6 +25,7 @@ Napi::Object QTreeWidgetWrap::init(Napi::Env env, Napi::Object exports) { InstanceMethod("setHeaderLabels", &QTreeWidgetWrap::setHeaderLabels), InstanceMethod("setItemWidget", &QTreeWidgetWrap::setItemWidget), InstanceMethod("currentItem", &QTreeWidgetWrap::currentItem), + InstanceMethod("findItems", &QTreeWidgetWrap::findItems), QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QTreeWidgetWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); @@ -219,3 +220,24 @@ Napi::Value QTreeWidgetWrap::currentItem(const Napi::CallbackInfo& info) { return value; } + +Napi::Value QTreeWidgetWrap::findItems(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + Napi::String napiText = info[0].As(); + std::string text = napiText.Utf8Value(); + int flag = info[1].As().Int32Value(); + int column = info[2].As().Int32Value(); + QList items = this->instance->findItems(QString::fromUtf8(text.c_str()), Qt::MatchFlags(flag), column); + Napi::Array napiItems = Napi::Array::New(env, items.size()); + for (int i = 0; i < items.size(); i++) { + QTreeWidgetItem* item = items[i]; + // disable deletion of the native instance for these by passing true + Napi::Object val = QTreeWidgetItemWrap::constructor.New( + {Napi::External::New(env, item), + Napi::Boolean::New(env, true)}); + napiItems[i] = val; + } + return napiItems; +} diff --git a/src/cpp/lib/QtWidgets/QTreeWidgetItem/qtreewidgetitem_wrap.cpp b/src/cpp/lib/QtWidgets/QTreeWidgetItem/qtreewidgetitem_wrap.cpp index e0fa8be77..e145b11f3 100644 --- a/src/cpp/lib/QtWidgets/QTreeWidgetItem/qtreewidgetitem_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTreeWidgetItem/qtreewidgetitem_wrap.cpp @@ -27,6 +27,8 @@ Napi::Object QTreeWidgetItemWrap::init(Napi::Env env, Napi::Object exports) { InstanceMethod("flags", &QTreeWidgetItemWrap::flags), InstanceMethod("setData", &QTreeWidgetItemWrap::setData), InstanceMethod("data", &QTreeWidgetItemWrap::data), + InstanceMethod("setHidden", &QTreeWidgetItemWrap::setHidden), + InstanceMethod("isHidden", &QTreeWidgetItemWrap::isHidden), COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE(QTreeWidgetItemWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); @@ -280,4 +282,21 @@ Napi::Value QTreeWidgetItemWrap::data(const Napi::CallbackInfo &info) { {Napi::External::New(env, new QVariant(variant))}); return instance; -} \ No newline at end of file +} + +Napi::Value QTreeWidgetItemWrap::setHidden(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + Napi::Boolean hide = info[0].As(); + this->instance->setHidden(hide.Value()); + return env.Null(); +} + +Napi::Value QTreeWidgetItemWrap::isHidden(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + + bool hide = this->instance->isHidden(); + return Napi::Boolean::New(env, hide); +} + diff --git a/src/demo.ts b/src/demo.ts index 6fd2701e0..09495475e 100644 --- a/src/demo.ts +++ b/src/demo.ts @@ -1,28 +1,57 @@ -import { QTabWidget } from './lib/QtWidgets/QTabWidget'; -import { QLabel } from './lib/QtWidgets/QLabel'; -import { QIcon } from './lib/QtGui/QIcon'; +import { QMainWindow, QWidget, FlexLayout, QTreeWidgetItem, QTreeWidget, QLineEdit, MatchFlag } from './index'; -const icon = new QIcon('/Users/atulr/Project/nodegui/nodegui/src/lib/QtGui/__tests__/assets/nodegui.png'); -const title1 = 'title 1'; -const title2 = 'title 2'; -const tabContent1 = new QLabel(); -const tabContent2 = new QLabel(); -const newTabContent = new QLabel(); +const win = new QMainWindow(); +const center = new QWidget(); +center.setLayout(new FlexLayout()); -tabContent1.setText('test text1'); -tabContent2.setText('test text2'); -newTabContent.setText('new inserted tab'); +win.setCentralWidget(center); -const tabs = new QTabWidget(); +const fruitTree = new QTreeWidget(); +fruitTree.setSortingEnabled(true); -tabs.addTab(tabContent1, icon, title1); -tabs.addTab(tabContent2, icon, title2); +fruitTree.setHeaderLabels(['Fruit', 'Price']); -// demo for the tab text change -tabs.setTabText(0, 'new title 1'); +const fruitObj = [ + { + fruit: 'Banana', + price: '2.5', + }, + { + fruit: 'Apple', + price: '1.0', + }, + { + fruit: 'Strawberry', + price: '2.5', + }, + { + fruit: 'Orange', + price: '1.5', + }, +]; -tabs.insertTab(0, newTabContent, icon, 'new inserted tab'); +const items = []; -tabs.show(); +for (const element of fruitObj) { + const fruitItem = new QTreeWidgetItem(fruitTree, [element.fruit, element.price]); + items.push(fruitItem); +} -(global as any).tabs = tabs; +fruitTree.addTopLevelItems(items); + +const filterLineEdit = new QLineEdit(); +filterLineEdit.setPlaceholderText('Filter...'); +filterLineEdit.addEventListener('returnPressed', () => { + const filterText = filterLineEdit.text(); + const foundItems = fruitTree + .findItems(filterText, MatchFlag.MatchContains, 0) + .concat(fruitTree.findItems(filterText, MatchFlag.MatchContains, 1)); + fruitTree.topLevelItems.forEach(item => item.setHidden(true)); + foundItems.forEach(item => item.setHidden(false)); +}); + +center.layout?.addWidget(filterLineEdit); +center.layout?.addWidget(fruitTree); + +win.show(); +(global as any).win = win; diff --git a/src/lib/QtWidgets/QTreeWidget.ts b/src/lib/QtWidgets/QTreeWidget.ts index f5324e291..a498cbfd7 100644 --- a/src/lib/QtWidgets/QTreeWidget.ts +++ b/src/lib/QtWidgets/QTreeWidget.ts @@ -3,6 +3,7 @@ import { NodeWidget, QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; import { QTreeWidgetItem } from './QTreeWidgetItem'; +import { MatchFlag } from '../..'; /** @@ -147,6 +148,21 @@ export class QTreeWidget extends QAbstractScrollArea { currentItem(): QTreeWidgetItem { return new QTreeWidgetItem(this.native.currentItem()); } + + /** + * Sets if columns can be sorted by clicking on its header + * @param enable Sorting enabled or disabled + */ + setSortingEnabled(enable: boolean): void { + this.native.setProperty('sortingEnabled', enable); + } + + findItems(text: string, flags: MatchFlag, column: number): QTreeWidgetItem[] { + const nativeItems = this.native.findItems(text, flags, column); + return nativeItems.map(function(eachItem: QTreeWidgetItem) { + return new QTreeWidgetItem(eachItem); + }); + } } export interface QTreeWidgetSignals extends QAbstractScrollAreaSignals { diff --git a/src/lib/QtWidgets/QTreeWidgetItem.ts b/src/lib/QtWidgets/QTreeWidgetItem.ts index f12042849..304eb4f66 100644 --- a/src/lib/QtWidgets/QTreeWidgetItem.ts +++ b/src/lib/QtWidgets/QTreeWidgetItem.ts @@ -155,4 +155,12 @@ export class QTreeWidgetItem extends Component { data(column: number, role: ItemDataRole): QVariant { return this.native.data(column, role); } + + setHidden(hide: boolean): void { + this.native.setHidden(hide); + } + + isHidden(): boolean { + return this.native.isHidden(); + } }