Creates an event without populating any members and without sending it. See dispatch
This is the widget that emitted the event.
This is an internal implementation detail you should not use. It would be private if the language allowed it and it may be removed without notice.
This is an internal implementation detail you should not use. It would be private if the language allowed it and it may be removed without notice.
hints as to whether preventDefault will actually do anything. not entirely reliable.
this dispatches the element using the capture -> target -> bubble process
Implementations for the ReflectableProperties interface/
Prevents the default event handler (if there is one) from being called
Events should generally follow the propagation model, but there's some exceptions to that rule. If so, they should override this to return false. In that case, only bubbling event handlers on the target itself and capturing event handlers on the containing window will be called. (That is, dispatch will call sendDirectly instead of doing the normal capture -> target -> bubble process.)
this sends it only to the target. If you want propagation, use dispatch() instead.
Implementations for the ReflectableProperties interface/
Stops the event propagation immediately.
You can mix this into child class to register some boilerplate. It includes the EventString member, a constructor, and implementations of the dynamic get data interfaces.
Note: likely to be deprecated at some point.
This is the widget that emitted the event.
Iterates the event's properties as strings. Note that keys may be repeated and a get property request may call your sink with null. It it does, it means the key either doesn't request or cannot be represented by json in the current implementation.
Requests a property to be delivered to you as a string, through your sink delegate.
Sets the given property, if it exists, to the given value, if possible. If strIsJson is true, it will json decode (if the implementation wants to) then apply the value, otherwise it will treat it as a plain string.
setPropertyFromString possible return values
You can mix this in to get an implementation in child classes. This does setPropertyFromString.
You can mix this in to get an implementation in child classes. This does getPropertyAsString and getPropertiesList.
Minigui's event model is based on the web browser. An event has a name, a target, and an associated data object. It starts from the window and works its way down through the target through all intermediate Widgets, triggering capture phase handlers as it goes, then goes back up again all the way back to the window, triggering bubble phase handlers. At the end, if Event.preventDefault has not been called, it calls the target widget's default handlers for the event (please note that default handlers will be called even if Event.stopPropagation was called; that just stops it from calling other handlers in the widget tree, but the default happens whenever propagation is done, not only if it gets to the end of the chain).
This model has several nice points:
There's a few downsides though:
In May 2021, I started to adjust this model to minigui takes better advantage of D over Javascript while keeping the benefits - and most compatibility with - the existing model. The main idea is to simply use a D object type which provides a static interface as well as a built-in event name. Then, a new static interface allows you to see what an event can emit and attach handlers to it similarly to C#, which just forwards to the JS style api. They're fully compatible so you can still delegate to a parent and use custom events as well as using the runtime dynamic access, in addition to having a little more help from the D compiler and documentation generator.
Your code would change like this:
// old widget.addEventListener("keydown", (Event ev) { ... }, /* optional arg */ useCapture ); // new widget.addEventListener((KeyDownEvent ev) { ... }, /* optional arg */ useCapture );
The old-style code will still work, but using certain members of the Event class will generate deprecation warnings. Changing handlers to the new style will silence all those warnings at once without requiring any other changes to your code.
All you have to do is replace the string with a specific Event subclass. It will figure out the event string from the class.
Alternatively, you can cast the Event yourself to the appropriate subclass, but it is easier to let the library do it for you!
Thus the family of functions are:
Widget.addEventListener is the fully-flexible base method. It has two main overload families: one with the string and one without. The one with the string takes the Event object, the one without determines the string from the type you pass. The string "*" matches ALL events that pass through.
Widget.addDirectEventListener is addEventListener, but only calls the handler if target == this. Useful for something you can't afford to delegate.
Widget.setDefaultEventHandler is what is called if no preventDefault was called. This should be called in the widget's constructor to set default behaivor. Default event handlers are only called on the event target.
Let's implement a custom widget that can emit a ChangeEvent describing its checked property:
class MyCheckbox : Widget { /// This gives a chance to document it and generates a convenience function to send it and attach handlers. /// It is NOT actually required but should be used whenever possible. mixin Emits!(ChangeEvent!bool); this(Widget parent) { super(parent); setDefaultEventHandler((ClickEvent) { checked = !checked; }); } private bool _checked; @property bool checked() { return _checked; } @property void checked(bool set) { _checked = set; emit!(ChangeEvent!bool)(&checked); } }
To avoid clashing in the string namespace, your events should use your module and class name as the event string. The simple code mixin Register; in your Event subclass will do this for you.
class MyEvent : Event { this(Widget target) { super(EventString, target); } mixin Register; // adds EventString and other reflection information }
Then declare that it is sent with the Emits mixin, so you can use Widget.emit to dispatch it.
Prior to May 2021, Event had a set of pre-made members with no extensibility (outside of diy casts) and no static checks on field presence.
After that, those old pre-made members are deprecated accessors and the fields are moved to child classes. To transition, change string events to typed events or do a dynamic cast (don't forget the null check!) in your handler.
Represents an event that is currently being processed.