Add way for JS to stop event processing in QObject::event() (#850)
This adds a couple small methods on `QObject` which makes it possible for JS code to indicate to the currently running `QObject::event()` override method whether it should allow more processing of an event or to stop processing and not call super class `event()` method. This is Qt recommended (C++) way of overriding event behaviour and stopping default behaviour.
This commit is contained in:
parent
281a89508b
commit
4eebad6f5f
@ -15,7 +15,7 @@ class DLL_EXPORT EventWidget {
|
||||
void subscribeToQtEvent(std::string evtString);
|
||||
void unSubscribeToQtEvent(std::string evtString);
|
||||
|
||||
void event(QEvent* event);
|
||||
bool event(QEvent* event);
|
||||
|
||||
void connectSignalsToEventEmitter();
|
||||
|
||||
|
||||
@ -52,7 +52,9 @@
|
||||
#ifndef EVENTWIDGET_IMPLEMENTATIONS
|
||||
#define EVENTWIDGET_IMPLEMENTATIONS(BaseWidgetName) \
|
||||
bool event(QEvent* event) override { \
|
||||
EventWidget::event(event); \
|
||||
if (EventWidget::event(event)) { \
|
||||
return true; \
|
||||
} \
|
||||
return BaseWidgetName::event(event); \
|
||||
}
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ void EventWidget::unSubscribeToQtEvent(std::string evtString) {
|
||||
}
|
||||
}
|
||||
|
||||
void EventWidget::event(QEvent* event) {
|
||||
bool EventWidget::event(QEvent* event) {
|
||||
if (this->emitOnNode) {
|
||||
try {
|
||||
QEvent::Type evtType = event->type();
|
||||
@ -40,11 +40,13 @@ void EventWidget::event(QEvent* event) {
|
||||
std::vector<napi_value> args = {Napi::String::New(env, eventTypeString),
|
||||
nativeEvent};
|
||||
|
||||
this->emitOnNode.Call(args);
|
||||
Napi::Value returnCode = this->emitOnNode.Call(args);
|
||||
return returnCode.As<Napi::Boolean>().Value();
|
||||
} catch (...) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EventWidget::connectSignalsToEventEmitter() {
|
||||
|
||||
@ -35,19 +35,28 @@ view.addEventListener(WidgetEventTypes.MouseMove, () => {
|
||||
*/
|
||||
export abstract class EventWidget<Signals extends unknown> extends Component {
|
||||
private emitter: EventEmitter;
|
||||
private _isEventProcessed = false;
|
||||
constructor(native: NativeElement) {
|
||||
super();
|
||||
if (native.initNodeEventEmitter) {
|
||||
this.emitter = new EventEmitter();
|
||||
this.emitter.emit = wrapWithActivateUvLoop(this.emitter.emit.bind(this.emitter));
|
||||
const logExceptions = (event: string | symbol, ...args: any[]): boolean => {
|
||||
// Preserve the value of `_isQObjectEventProcessed` as we dispatch this event
|
||||
// to JS land, and restore it afterwards. This lets us support recursive event
|
||||
// dispatches on the same object.
|
||||
const previousEventProcessed = this._isEventProcessed;
|
||||
this._isEventProcessed = false;
|
||||
try {
|
||||
return this.emitter.emit(event, ...args);
|
||||
this.emitter.emit(event, ...args);
|
||||
} catch (e) {
|
||||
console.log(`An exception was thrown while dispatching an event of type '${event.toString()}':`);
|
||||
console.log(e);
|
||||
}
|
||||
return false;
|
||||
|
||||
const returnCode = this._isEventProcessed;
|
||||
this._isEventProcessed = previousEventProcessed;
|
||||
return returnCode;
|
||||
};
|
||||
native.initNodeEventEmitter(logExceptions);
|
||||
} else {
|
||||
@ -56,12 +65,41 @@ export abstract class EventWidget<Signals extends unknown> extends Component {
|
||||
addDefaultErrorHandler(native, this.emitter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the state of the event processed flag
|
||||
*
|
||||
* See `setEventProcessed()`.
|
||||
*
|
||||
* @returns boolean True if the current event is flagged as processed.
|
||||
*/
|
||||
eventProcessed(): boolean {
|
||||
return this._isEventProcessed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the current event as having been processed
|
||||
*
|
||||
* This method is used to indicate that the currently dispatched event
|
||||
* has been processed and no further processing by superclasses is
|
||||
* required. It only makes sense to call this method from an event
|
||||
* handler.
|
||||
*
|
||||
* When set, this flag will cause NodeGui's `QObject::event()` method to
|
||||
* return true and not call the superclass `event()`, effectively preventing
|
||||
* any further processing on this event.
|
||||
*
|
||||
* @param isProcessed true if the event has been processed.
|
||||
*/
|
||||
setEventProcessed(isProcessed: boolean): void {
|
||||
this._isEventProcessed = isProcessed;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
@param signalType SignalType is a signal from the widgets signals interface.
|
||||
@param callback Corresponding callback for the signal as mentioned in the widget's signal interface
|
||||
@returns void
|
||||
|
||||
|
||||
For example in the case of QPushButton:
|
||||
```js
|
||||
const button = new QPushButton();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user