[mxGraph] source learning: (4) mxEventSource

Posted by ramma03 on Sun, 15 Dec 2019 20:23:32 +0100

mxGraph inherits from mxEventSource, so let's first learn about mxEventSource.

1. role

mxEventSource is the base class of the object to assign named events, which is inherited in the prototype chain way, as follows:

function MyClass() { };
MyClass.prototype = new mxEventSource();
MyClass.prototype.constructor = MyClass;

The following subclasses already exist in the mxGraph Library: mxGraphModel, mxGraph, mxGraphView, mxEditor, mxCellOverlay, mxToolbar, mxWindow.

The mxEventSource constructor is as follows, you can specify an event source:

function mxEventSource(eventSource) {
    this.setEventSource(eventSource);
}

2. Prototype properties

Three properties defined by mxEventSource are prototype properties:

// Stores the event name and the associated listener in the array. The array contains the event name followed by the corresponding listener for each registered listener.
mxEventSource.prototype.eventListeners = null;

// Specifies whether events can be triggered. The default is true.
mxEventSource.prototype.eventsEnabled = true;

// Optional source of the event. The default value is null.
mxEventSource.prototype.eventSource = null;

The getter and setter of eventsEnabled and eventSource are also defined.

3. Prototype method

mxEventSource defines three prototype methods for adding, removing, and triggering listeners:

/**
 * Binds the specified function to the given event name. If no event name is given, the listener is registered for all events.
 * The parameters for the listener are the sender and < mxeventobject >.
 */
mxEventSource.prototype.addListener = function (name, funct) {
    if (this.eventListeners == null) {
        this.eventListeners = [];
    }

    this.eventListeners.push(name);
    this.eventListeners.push(funct);
};

/**
 * Remove all occurrences of the given listeners from < EventListeners >.
 */
mxEventSource.prototype.removeListener = function (funct) {
    if (this.eventListeners != null) {
        var i = 0;

        while (i < this.eventListeners.length) {
            if (this.eventListeners[i + 1] == funct) {
                this.eventListeners.splice(i, 2);
            } else {
                i += 2;
            }
        }
    }
};

/**
 * Assign the given event to the listener registered for the event. The sender parameter is optional.
 * The current execution scope ("this") is used for listener calls (see < mxutils. Bind >).
 *
 * evt - The < mxeventobject >
 * sender - Optional sender to pass to the listener. The default value is the return value of < geteventsource >
 */
mxEventSource.prototype.fireEvent = function (evt, sender) {
    if (this.eventListeners != null && this.isEventsEnabled()) {
        if (evt == null) {
            evt = new mxEventObject();
        }

        if (sender == null) {
            sender = this.getEventSource();
        }

        if (sender == null) {
            sender = this;
        }

        var args = [sender, evt];

        for (var i = 0; i < this.eventListeners.length; i += 2) {
            var listen = this.eventListeners[i];

            if (listen == null || listen == evt.getName()) {
                this.eventListeners[i + 1].apply(this, args);
            }
        }
    }
};

4. mxEventObject

mxEventObject used in mxEventSource.fireEvent above is a wrapper for all properties of a single event. In addition, it provides the ability to trigger events and check whether it is triggered.

The mxEventObject's constructor is as follows to construct a new event object with the specified name. You can attach an optional sequence of key value pairs to define properties:

function mxEventObject(name) {
    this.name = name;
    this.properties = [];

    for (var i = 1; i < arguments.length; i += 2) {
        if (arguments[i + 1] != null) {
            this.properties[arguments[i]] = arguments[i + 1];
        }
    }
}

The following prototype properties are defined:

// Event name
mxEventObject.prototype.name = null;

// Save properties as associative arrays
mxEventObject.prototype.properties = null;

// Trigger status. The default value is false
mxEventObject.prototype.consumed = false;

In addition to the getter s of name and properties, three prototype methods are defined:

/**
 * Returns the properties of the given key.
 */
mxEventObject.prototype.getProperty = function (key) {
    return this.properties[key];
};

/**
 * Returns true if the event has been triggered.
 */
mxEventObject.prototype.isConsumed = function () {
    return this.consumed;
};

/**
 * Function: consume
 *
 * Trigger event
 */
mxEventObject.prototype.consume = function () {
    this.consumed = true;
};

mxEventSource and mxEventObject interact by event name. First register the event and its listener in mxEventSource, then pass mxEventObject to mxEventSource to trigger the corresponding event listener, and call the listener with mxEventObject as a parameter, as shown in the following figure: