diff --git a/CMakeLists.txt b/CMakeLists.txt index 004747184..ba020f256 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,8 @@ add_library(${CORE_WIDGETS_ADDON} SHARED "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QEvent/QDragMoveEvent/qdragmoveevent_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QEvent/QDragLeaveEvent/qdragleaveevent_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QEvent/QResizeEvent/qresizeevent_wrap.cpp" + "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QEvent/QInputMethodEvent/qinputmethodevent_wrap.cpp" + "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QEvent/QInputMethodQueryEvent/qinputmethodqueryevent_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QFontDatabase/qfontdatabase_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QFontMetrics/qfontmetrics_wrap.cpp" "${PROJECT_SOURCE_DIR}/src/cpp/lib/QtGui/QFontMetricsF/qfontmetricsf_wrap.cpp" diff --git a/src/cpp/include/nodegui/QtGui/QEvent/QInputMethodEvent/qinputmethodevent_wrap.h b/src/cpp/include/nodegui/QtGui/QEvent/QInputMethodEvent/qinputmethodevent_wrap.h new file mode 100644 index 000000000..ff13e9b7a --- /dev/null +++ b/src/cpp/include/nodegui/QtGui/QEvent/QInputMethodEvent/qinputmethodevent_wrap.h @@ -0,0 +1,32 @@ +#pragma once + +#include + +#include + +#include "Extras/Export/export.h" +#include "QtGui/QEvent/QEvent/qevent_macro.h" +#include "core/Component/component_macro.h" + +class DLL_EXPORT QInputMethodEventWrap + : public Napi::ObjectWrap { + COMPONENT_WRAPPED_METHODS_DECLARATION + QEVENT_WRAPPED_METHODS_DECLARATION + + private: + QInputMethodEvent* instance; + + public: + static Napi::Object init(Napi::Env env, Napi::Object exports); + QInputMethodEventWrap(const Napi::CallbackInfo& info); + ~QInputMethodEventWrap(); + QInputMethodEvent* getInternalInstance(); + // class constructor + static Napi::FunctionReference constructor; + // wrapped methods + Napi::Value commitString(const Napi::CallbackInfo& info); + Napi::Value preeditString(const Napi::CallbackInfo& info); + Napi::Value replacementLength(const Napi::CallbackInfo& info); + Napi::Value replacementStart(const Napi::CallbackInfo& info); + Napi::Value setCommitString(const Napi::CallbackInfo& info); +}; diff --git a/src/cpp/include/nodegui/QtGui/QEvent/QInputMethodQueryEvent/qinputmethodqueryevent_wrap.h b/src/cpp/include/nodegui/QtGui/QEvent/QInputMethodQueryEvent/qinputmethodqueryevent_wrap.h new file mode 100644 index 000000000..f15b4249c --- /dev/null +++ b/src/cpp/include/nodegui/QtGui/QEvent/QInputMethodQueryEvent/qinputmethodqueryevent_wrap.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +#include + +#include "Extras/Export/export.h" +#include "QtGui/QEvent/QEvent/qevent_macro.h" +#include "core/Component/component_macro.h" + +class DLL_EXPORT QInputMethodQueryEventWrap + : public Napi::ObjectWrap { + COMPONENT_WRAPPED_METHODS_DECLARATION + QEVENT_WRAPPED_METHODS_DECLARATION + + private: + QInputMethodQueryEvent* instance; + + public: + static Napi::Object init(Napi::Env env, Napi::Object exports); + QInputMethodQueryEventWrap(const Napi::CallbackInfo& info); + ~QInputMethodQueryEventWrap(); + QInputMethodQueryEvent* getInternalInstance(); + // class constructor + static Napi::FunctionReference constructor; + // wrapped methods + Napi::Value queries(const Napi::CallbackInfo& info); + Napi::Value setValue(const Napi::CallbackInfo& info); + Napi::Value value(const Napi::CallbackInfo& info); +}; \ No newline at end of file diff --git a/src/cpp/include/nodegui/QtWidgets/QWidget/nwidget.hpp b/src/cpp/include/nodegui/QtWidgets/QWidget/nwidget.hpp index d0dc970cb..99965b2dd 100644 --- a/src/cpp/include/nodegui/QtWidgets/QWidget/nwidget.hpp +++ b/src/cpp/include/nodegui/QtWidgets/QWidget/nwidget.hpp @@ -23,4 +23,8 @@ class DLL_EXPORT NWidget : public QWidget, public NodeWidget { } virtual void connectSignalsToEventEmitter() { QWIDGET_SIGNALS } + + void _protected_updateMicroFocus(Qt::InputMethodQuery query) { + updateMicroFocus(query); + } }; diff --git a/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h b/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h index da1d49c9e..d827d6caa 100644 --- a/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h +++ b/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h @@ -765,6 +765,16 @@ Napi::Env env = info.Env(); \ int result = this->instance->widthMM(); \ return Napi::Number::New(env, result); \ + } \ + Napi::Value updateMicroFocus(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + NWidget* nwidget = dynamic_cast(this->instance.data()); \ + if (nwidget) { \ + Qt::InputMethodQuery query = static_cast( \ + info[0].As().Int32Value()); \ + nwidget->_protected_updateMicroFocus(query); \ + } \ + return env.Null(); \ } #endif // QWIDGET_WRAPPED_METHODS_DECLARATION @@ -884,7 +894,8 @@ InstanceMethod("paintingActive", &WidgetWrapName::paintingActive), \ InstanceMethod("physicalDpiX", &WidgetWrapName::physicalDpiX), \ InstanceMethod("physicalDpiY", &WidgetWrapName::physicalDpiY), \ - InstanceMethod("widthMM", &WidgetWrapName::widthMM), + InstanceMethod("widthMM", &WidgetWrapName::widthMM), \ + InstanceMethod("updateMicroFocus", &WidgetWrapName::updateMicroFocus), #endif // QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE diff --git a/src/cpp/lib/QtGui/QEvent/QInputMethodEvent/qinputmethodevent_wrap.cpp b/src/cpp/lib/QtGui/QEvent/QInputMethodEvent/qinputmethodevent_wrap.cpp new file mode 100644 index 000000000..0f10ce4d9 --- /dev/null +++ b/src/cpp/lib/QtGui/QEvent/QInputMethodEvent/qinputmethodevent_wrap.cpp @@ -0,0 +1,90 @@ +#include "QtGui/QEvent/QInputMethodEvent/qinputmethodevent_wrap.h" + +#include + +#include "Extras/Utils/nutils.h" + +Napi::FunctionReference QInputMethodEventWrap::constructor; + +Napi::Object QInputMethodEventWrap::init(Napi::Env env, Napi::Object exports) { + Napi::HandleScope scope(env); + char CLASSNAME[] = "QInputMethodEvent"; + Napi::Function func = DefineClass( + env, CLASSNAME, + {InstanceMethod("commitString", &QInputMethodEventWrap::commitString), + InstanceMethod("preeditString", &QInputMethodEventWrap::preeditString), + InstanceMethod("replacementLength", + &QInputMethodEventWrap::replacementLength), + InstanceMethod("replacementStart", + &QInputMethodEventWrap::replacementStart), + InstanceMethod("setCommitString", + &QInputMethodEventWrap::setCommitString), + + COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE(QInputMethodEventWrap) + QEVENT_WRAPPED_METHODS_EXPORT_DEFINE(QInputMethodEventWrap)}); + constructor = Napi::Persistent(func); + exports.Set(CLASSNAME, func); + return exports; +} + +QInputMethodEvent* QInputMethodEventWrap::getInternalInstance() { + return this->instance; +} + +QInputMethodEventWrap::QInputMethodEventWrap(const Napi::CallbackInfo& info) + : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + if (info.Length() == 1) { + Napi::External eventObject = + info[0].As>(); + this->instance = static_cast(eventObject.Data()); + } else { + Napi::TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + } + this->rawData = extrautils::configureComponent(this->getInternalInstance()); +} + +QInputMethodEventWrap::~QInputMethodEventWrap() { + // Do not destroy instance here. It will be done by Qt Event loop. +} + +Napi::Value QInputMethodEventWrap::setCommitString( + const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::String setCommitString = info[0].As(); + int replaceFrom = info[1].As().Int32Value(); + int replaceLength = info[2].As().Int32Value(); + this->instance->setCommitString( + QString::fromStdString(setCommitString.Utf8Value()), replaceFrom, + replaceLength); + return env.Null(); +} + +Napi::Value QInputMethodEventWrap::commitString( + const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + QString commitString = this->instance->commitString(); + return Napi::Value::From(env, commitString.toStdString()); +} + +Napi::Value QInputMethodEventWrap::preeditString( + const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + QString preeditString = this->instance->preeditString(); + return Napi::Value::From(env, preeditString.toStdString()); +} + +Napi::Value QInputMethodEventWrap::replacementLength( + const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + int x = this->instance->replacementLength(); + return Napi::Number::From(env, x); +} + +Napi::Value QInputMethodEventWrap::replacementStart( + const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + int x = this->instance->replacementStart(); + return Napi::Number::From(env, x); +} diff --git a/src/cpp/lib/QtGui/QEvent/QInputMethodQueryEvent/qinputmethodqueryevent_wrap.cpp b/src/cpp/lib/QtGui/QEvent/QInputMethodQueryEvent/qinputmethodqueryevent_wrap.cpp new file mode 100644 index 000000000..76517dacb --- /dev/null +++ b/src/cpp/lib/QtGui/QEvent/QInputMethodQueryEvent/qinputmethodqueryevent_wrap.cpp @@ -0,0 +1,79 @@ +#include "QtGui/QEvent/QInputMethodQueryEvent/qinputmethodqueryevent_wrap.h" + +#include + +#include "Extras/Utils/nutils.h" +#include "QtCore/QVariant/qvariant_wrap.h" + +Napi::FunctionReference QInputMethodQueryEventWrap::constructor; + +Napi::Object QInputMethodQueryEventWrap::init(Napi::Env env, + Napi::Object exports) { + Napi::HandleScope scope(env); + char CLASSNAME[] = "QInputMethodQueryEvent"; + Napi::Function func = DefineClass( + env, CLASSNAME, + {InstanceMethod("queries", &QInputMethodQueryEventWrap::queries), + InstanceMethod("setValue", &QInputMethodQueryEventWrap::setValue), + InstanceMethod("value", &QInputMethodQueryEventWrap::value), + + COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE(QInputMethodQueryEventWrap) + QEVENT_WRAPPED_METHODS_EXPORT_DEFINE(QInputMethodQueryEventWrap)}); + constructor = Napi::Persistent(func); + exports.Set(CLASSNAME, func); + return exports; +} + +QInputMethodQueryEvent* QInputMethodQueryEventWrap::getInternalInstance() { + return this->instance; +} + +QInputMethodQueryEventWrap::QInputMethodQueryEventWrap( + const Napi::CallbackInfo& info) + : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + if (info.Length() == 1) { + Napi::External eventObject = + info[0].As>(); + this->instance = static_cast(eventObject.Data()); + } else { + Napi::TypeError::New(env, "Wrong number of arguments") + .ThrowAsJavaScriptException(); + } + this->rawData = extrautils::configureComponent(this->getInternalInstance()); +} + +QInputMethodQueryEventWrap::~QInputMethodQueryEventWrap() { + // Do not destroy instance here. It will be done by Qt Event loop. +} + +Napi::Value QInputMethodQueryEventWrap::queries( + const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Qt::InputMethodQueries queries = this->instance->queries(); + return Napi::Number::From(env, queries.toInt()); +} + +Napi::Value QInputMethodQueryEventWrap::setValue( + const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Qt::InputMethodQuery query = static_cast( + info[0].As().Int32Value()); + Napi::Value value = info[1]; + QVariant* valueVariant = extrautils::convertToQVariant(env, value); + this->instance->setValue(query, *valueVariant); + delete valueVariant; + return env.Null(); +} + +Napi::Value QInputMethodQueryEventWrap::value(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + + Qt::InputMethodQuery query = static_cast( + info[0].As().Int32Value()); + QVariant value = this->instance->value(query); + + auto instance = QVariantWrap::constructor.New( + {Napi::External::New(env, new QVariant(value))}); + return instance; +} diff --git a/src/cpp/lib/QtWidgets/QTableWidget/qtablewidget_wrap.cpp b/src/cpp/lib/QtWidgets/QTableWidget/qtablewidget_wrap.cpp index 6e4d34d19..025f984c4 100644 --- a/src/cpp/lib/QtWidgets/QTableWidget/qtablewidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTableWidget/qtablewidget_wrap.cpp @@ -84,8 +84,8 @@ Napi::Object QTableWidgetWrap::init(Napi::Env env, Napi::Object exports) { InstanceMethod("visualRow", &QTableWidgetWrap::visualRow), InstanceMethod("clearSelection", &QTableWidgetWrap::clearSelection), InstanceMethod("selectAll", &QTableWidgetWrap::selectAll), - InstanceMethod("scrollToBottom", &QTableWidgetWrap::scrollToBottom), - InstanceMethod("scrollToTop", &QTableWidgetWrap::scrollToTop), + InstanceMethod("scrollToBottom", &QTableWidgetWrap::scrollToBottom), + InstanceMethod("scrollToTop", &QTableWidgetWrap::scrollToTop), QABSTRACTSCROLLAREA_WRAPPED_METHODS_EXPORT_DEFINE(QTableWidgetWrap)}); constructor = Napi::Persistent(func); diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index bd4627072..df586fb89 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -27,6 +27,8 @@ #include "QtGui/QEvent/QDragLeaveEvent/qdragleaveevent_wrap.h" #include "QtGui/QEvent/QDragMoveEvent/qdragmoveevent_wrap.h" #include "QtGui/QEvent/QDropEvent/qdropevent_wrap.h" +#include "QtGui/QEvent/QInputMethodEvent/qinputmethodevent_wrap.h" +#include "QtGui/QEvent/QInputMethodQueryEvent/qinputmethodqueryevent_wrap.h" #include "QtGui/QEvent/QKeyEvent/qkeyevent_wrap.h" #include "QtGui/QEvent/QMouseEvent/qmouseevent_wrap.h" #include "QtGui/QEvent/QMoveEvent/qmoveevent_wrap.h" @@ -246,6 +248,8 @@ Napi::Object Main(Napi::Env env, Napi::Object exports) { QResizeEventWrap::init(env, exports); QTimerEventWrap::init(env, exports); QAbstractItemDelegateWrap::init(env, exports); + QInputMethodEventWrap::init(env, exports); + QInputMethodQueryEventWrap::init(env, exports); // Test CacheTestQObjectWrap::init(env, exports); diff --git a/src/index.ts b/src/index.ts index 18b318a2a..e85e2ec56 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,6 +22,8 @@ export { QFontDatabase, SystemFont, WritingSystem } from './lib/QtGui/QFontDatab export { QFontMetrics } from './lib/QtGui/QFontMetrics'; export { QFontMetricsF } from './lib/QtGui/QFontMetricsF'; // Events: Maybe a separate module ? +export { QInputMethodEvent } from './lib/QtGui/QEvent/QInputMethodEvent'; +export { QInputMethodQueryEvent } from './lib/QtGui/QEvent/QInputMethodQueryEvent'; export { QKeyEvent } from './lib/QtGui/QEvent/QKeyEvent'; export { QMouseEvent } from './lib/QtGui/QEvent/QMouseEvent'; export { QMoveEvent } from './lib/QtGui/QEvent/QMoveEvent'; diff --git a/src/lib/QtCore/QVariant.ts b/src/lib/QtCore/QVariant.ts index 1708bffa8..7493bb1e8 100644 --- a/src/lib/QtCore/QVariant.ts +++ b/src/lib/QtCore/QVariant.ts @@ -1,8 +1,9 @@ import { NativeElement, Component } from '../core/Component'; import addon from '../utils/addon'; import { checkIfNativeElement } from '../utils/helpers'; +import { QRect } from './QRect'; -export type QVariantType = NativeElement | string | string[] | number | boolean; +export type QVariantType = NativeElement | string | string[] | number | boolean | QRect; export class QVariant extends Component { constructor(); @@ -35,3 +36,14 @@ export class QVariant extends Component { return this.native.toStringList(); } } + +/** + * Get the correct native object which should be passed down to the + * C++ wrapper from a QVariantType object. + */ +export function nativeObjectFromVariantType(obj: QVariantType): any { + if (obj instanceof QRect) { + return obj.native; + } + return obj; +} diff --git a/src/lib/QtEnums/InputMethodQuery/index.ts b/src/lib/QtEnums/InputMethodQuery/index.ts index ca1b739fe..a94194c24 100644 --- a/src/lib/QtEnums/InputMethodQuery/index.ts +++ b/src/lib/QtEnums/InputMethodQuery/index.ts @@ -1,6 +1,5 @@ export enum InputMethodQuery { ImEnabled = 0x1, - ImMicroFocus = 0x2, ImCursorRectangle = 0x2, ImFont = 0x4, ImCursorPosition = 0x8, @@ -17,6 +16,7 @@ export enum InputMethodQuery { ImEnterKeyType = 0x2000, ImAnchorRectangle = 0x4000, ImInputItemClipRectangle = 0x8000, + ImReadOnly = 0x10000, //Masks: ImQueryAll = 0xffffffff, } diff --git a/src/lib/QtGui/QEvent/QInputMethodEvent.ts b/src/lib/QtGui/QEvent/QInputMethodEvent.ts new file mode 100644 index 000000000..02aad5482 --- /dev/null +++ b/src/lib/QtGui/QEvent/QInputMethodEvent.ts @@ -0,0 +1,24 @@ +import addon from '../../utils/addon'; +import { NativeRawPointer } from '../../core/Component'; +import { QEvent } from './QEvent'; + +export class QInputMethodEvent extends QEvent { + constructor(event: NativeRawPointer<'QEvent'>) { + super(new addon.QInputMethodEvent(event)); + } + commitString(): string { + return this.native.commitString(); + } + preeditString(): string { + return this.native.preeditString(); + } + replacementLength(): number { + return this.native.replacementLength(); + } + replacementStart(): number { + return this.native.replacementStart(); + } + setCommitString(commitString: string, replaceFrom = 0, replaceLength = 0): void { + this.native.setCommitString(commitString, replaceFrom, replaceLength); + } +} diff --git a/src/lib/QtGui/QEvent/QInputMethodQueryEvent.ts b/src/lib/QtGui/QEvent/QInputMethodQueryEvent.ts new file mode 100644 index 000000000..d294c15bc --- /dev/null +++ b/src/lib/QtGui/QEvent/QInputMethodQueryEvent.ts @@ -0,0 +1,28 @@ +import addon from '../../utils/addon'; +import { NativeRawPointer } from '../../core/Component'; +import { QVariant, QVariantType, nativeObjectFromVariantType } from '../../QtCore/QVariant'; +import { QEvent } from './QEvent'; + +/** + * Note: Qt performs some default processing for `QInputMethodQueryEvents`. + * When attaching an event listener via `addEventListener()` use the + * options object to specify that you want to run after the default + * processing, otherwise your `setValue()` calls will be overwritten. + */ +export class QInputMethodQueryEvent extends QEvent { + constructor(event: NativeRawPointer<'QEvent'>) { + super(new addon.QInputMethodQueryEvent(event)); + } + + queries(): number /* InputMethodQueries */ { + return this.native.queries(); + } + + setValue(query: number /* InputMethodQuery */, value: QVariantType): void { + this.native.setValue(query, nativeObjectFromVariantType(value)); + } + + value(query: number /* InputMethodQuery */): QVariant { + return new QVariant(this.native.value(query)); + } +} diff --git a/src/lib/QtWidgets/QWidget.ts b/src/lib/QtWidgets/QWidget.ts index a6125c6c6..b8a16f6c6 100644 --- a/src/lib/QtWidgets/QWidget.ts +++ b/src/lib/QtWidgets/QWidget.ts @@ -2,7 +2,7 @@ import addon from '../utils/addon'; import { QLayout } from './QLayout'; import { NativeElement } from '../core/Component'; import { FlexLayout } from '../core/FlexLayout'; -import { WidgetAttribute, WindowType, ContextMenuPolicy, FocusReason, FocusPolicy } from '../QtEnums'; +import { WidgetAttribute, WindowType, ContextMenuPolicy, FocusReason, FocusPolicy, InputMethodQuery } from '../QtEnums'; import { QIcon } from '../QtGui/QIcon'; import { QCursor } from '../QtGui/QCursor'; import { CursorShape, WindowState } from '../QtEnums'; @@ -193,7 +193,9 @@ export class QWidget extends Yo heightForWidth(w: number): number { return this.native.heightForWidth(w); } - // TODO: Qt::InputMethodHints inputMethodHints() const + inputMethodHints(): number { + return this.property('inputMethodHints').toInt(); + } // TODO: virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const // TODO: void insertAction(QAction *before, QAction *action) // TODO: void insertActions(QAction *before, QList actions) @@ -396,7 +398,9 @@ export class QWidget extends Yo setGraphicsEffect(effect: QGraphicsEffect): void { this.native.setGraphicsEffect(effect.native); } - // TODO: void setInputMethodHints(Qt::InputMethodHints hints) + setInputMethodHints(hints: number): void { + this.setProperty('inputMethodHints', hints); + } setInlineStyle(style: string, postprocess = true): void { if (postprocess) { this._rawInlineStyle = style; @@ -560,6 +564,11 @@ export class QWidget extends Yo updatesEnabled(): boolean { return this.property('updatesEnabled').toBool(); } + + updateMicroFocus(query: number = InputMethodQuery.ImQueryAll): void { + this.native.updateMicroFocus(query); + } + // TODO: QRegion visibleRegion() const whatsThis(): string { return this.property('whatsThis').toString();