Creates the widget and adds it to the parent.
Style properties are defined as an accessory class so they can be referenced and overridden independently, but they are nested so you can refer to them easily by name (e.g. generic Widget.Style vs Button.Style and such).
List of dynamic states made available to the style engine, for cases like CSS pseudo-classes and also used by default paint methods. It is stored in a 64 bit variable attached to the widget that you can update. The style cache is aware of the fact that these can frequently change.
Adds a child to the given position. This is protected because you generally shouldn't be calling this directly. Instead, construct widgets with the parent directly.
If the widget is a scrollable container, this should add the current scroll position to the given coordinates so the mouse events can be dispatched correctly.
Callback when the widget is added to another widget.
This is called when the widget is added to a window. It gives you a chance to set up event hooks.
Calculates the border box (that is, the full width/height of the widget, from border edge to border edge) for the given content box (the area between the padding)
Returns the current scaling factor as a logical dpi value for this widget. Generally speaking, this divided by 96 gives you the user scaling factor.
Default event handlers. These are called on the appropriate event unless Event.preventDefault is called on the event at some point through the bubbling process.
Returns the widget that disabled this. It might be this or one of its parents all the way up the chain, or null if the widget is not disabled by anything. You can check disabledReason on the return value (after the null check!) to get a hint to display to the user.
Virtual hook to update any caches or fonts you need on the event of a dpi scaling change.
Allows a class to easily dispatch its own statically-declared event (see Emits). The main benefit of using this over constructing an event yourself is simply that you ensure you haven't sent something you haven't documented you can send.
If encapsulatedChildren returns true, it changes the event handling mechanism to act as if events from the child widgets are actually targeted on this widget.
I don't actually like the name of this this draws a background on it
The initial size of the widget for layout calculations. Default is 0.
The initial size of the widget for layout calculations. Default is 0.
Finds the nearest descendant with the requested type and name. May return this.
Finds the child at the top of the z-order at the given coordinates (relative to the this widget's origin), or null if none are found.
Calls getByName with the generic type of Widget. Meant for script interop where instantiating a template is impossible.
Gets the computed style properties from the visual theme.
Implementations of ReflectableProperties interface. See the interface for details.
Returns the coordinates of this widget on the screen, relative to the upper left corner of the whole screen.
Called when a WM_COMMAND is sent to the associated hwnd.
Called when a WM_NOTIFY is sent to the associated hwnd.
Where stretchiness will grow from the flex basis, this shrinkiness will let it get smaller if needed to make room for other items.
Convenience method for showing = false
Returns true if this is the current focused widget inside the parent window. Please note it may return true when the window itself is unfocused. In that case, it indicates this widget will receive focuse again when the window does.
Called when the widget has been added to or remove from a parent window.
Responsible for actually painting the widget to the screen. The clip rectangle and coordinate translation in the WidgetPainter are pre-configured so you can draw independently.
Responsible for drawing the content as the theme engine is responsible for other elements.
This can be overridden by scroll things. It is responsible for actually calling paint. Do not override unless you've studied minigui.d's source code. There are no stability guarantees if you do override this; it can (and likely will) break without notice.
This function is called by the layout engine after it has updated the position (in variables x and y) and the size (in properties width and height) to give you a chance to update the actual position of the native child window (if there is one) or whatever.
Removes all child widgets from this. You should not use the removed widgets again.
Removes this widget from its parent.
Scales the given value to the system-reported DPI for the monitor on which the widget resides.
List of dynamic states made available to the style engine, for cases like CSS pseudo-classes and also used by default paint methods. It is stored in a 64 bit variable attached to the widget that you can update. The style cache is aware of the fact that these can frequently change.
Implementations of ReflectableProperties interface. See the interface for details.
Default event handlers. These are called on the appropriate event unless Event.preventDefault is called on the event at some point through the bubbling process.
Convenience method for showing = true
If you are a native window, show/hide it based on shouldShow and return true.
Shows or hides the window. Meant to be assigned as a property. If recalculate is true (the default), it recalculates the layout of the parent widget to use the space this widget being hidden frees up or make space for this widget to appear again.
Returns a "class list" that can be used by the visual theme's style engine via VisualTheme.getPropertyString if it chooses to do something like CSS.
Returns the style's tag name string this object uses.
Does the same as addEventListener's delegate overload, but adds an additional check to ensure the event you are subscribing to is actually emitted by the static type you are using. Since it works on static types, if you have a generic Widget, this can only subscribe to events declared as Emits inside Widget itself, not any child classes nor any child elements. If this is too restrictive, simply use addEventListener instead.
You can override this by hand, or use the OverrideStyle helper which is a bit less verbose.
Notifies the subclass that a widget was removed. If you keep auxillary data about your children, you can override this to help keep that data in sync.
Where stretchiness will grow from the flex basis, this shrinkiness will let it get smaller if needed to make room for other items.
This mixin overrides the useStyleProperties method to direct it toward your own style class. The basic usage is simple:
Returns the list of the widget's children.
If the widget is not enabled this string may be presented to the user when they try to use it. The exact manner and time it gets displayed is up to the implementation of the control.
List of dynamic states made available to the style engine, for cases like CSS pseudo-classes and also used by default paint methods. It is stored in a 64 bit variable attached to the widget that you can update. The style cache is aware of the fact that these can frequently change.
Determines whether the control is marked enabled. Disabled controls are generally displayed as greyed out and clicking on them does nothing. It is also possible for a control to be disabled because its parent is disabled, in which case this will still return true, but setting enabled = true may have no effect. Check disabledBy to see which parent caused it to be disabled.
The widget's current size.
Only the layout manager should be calling these.
Returns the widget's parent.
Returns the window to which this widget is attached.
The widget's current size.
Only the layout manager should be calling these.
API for the styleClassList
Default event handlers. These are called on the appropriate event unless Event.preventDefault is called on the event at some point through the bubbling process.
Not stable.
The native handle, if there is one.
The name is a string tag that is used to reference the widget from scripts, gui loaders, declarative ui templates, etc. Similar to a HTML id attribute. Names should be unique in a window.
This tip is displayed in the status bar (if there is one in the containing window) when the mouse moves over this widget.
The tab key cycles through widgets by the order of a.tabOrder < b.tabOrder. If they are equal, it does them in child order (which is typically the order they were added to the widget.)
If true, this widget can be focused via keyboard control with the tab key.
Child's position relative to the parent's origin. only the layout manager should be modifying this and even reading it is of limited utility. It may be made private at some point in the future without advance notice. Do NOT depend on it being available unless you are writing a layout manager.
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.
To create your own widget, you must inherit from it and create a constructor that passes a parent to super. Everything else after that is optional.
class MinimalWidget : Widget { this(Widget parent) { super(parent); } }
Broadly, there's two kinds of widgets: leaf widgets, which are intended to be the direct user-interactive components, and container widgets, which organize, lay out, and aggregate other widgets in the object tree. A special case of a container widget is Window, which represents a separate top-level window on the screen. Both leaf and container widgets inherit from Widget, so this distinction is more conventional than formal.
Among the things you'll most likely want to change in your custom widget:
You may explicitly set tabStop = true; to ensure you get it, even against future changes to the library, though that's the default right now.
Do this after calling the super constructor.
Generally, painting is a job for leaf widgets, since child widgets would obscure your drawing area anyway. However, it is your decision.
On Microsoft Windows, many widgets are also based on native controls. You can also do this if static if(UsingWin32Widgets) passes. You should use the helper function createWin32Window to create the window and let minigui do what it needs to do to create its bridge structures. This will populate Widget.hwnd which you can access later for communcating with the native window. You may also consider overriding Widget.handleWmCommand and Widget.handleWmNotify for the widget to translate those messages into appropriate minigui Events.
It is also possible to embed a SimpleWindow-based native window inside a widget. See OpenGlWidget's source code as an example.
Your own custom-drawn and native system controls can exist side-by-side.
Later I'll add more complete examples, but for now TextLabel and LabeledPasswordEdit are both simple widgets you can view implementation to get some ideas.
The Widget is the base class for minigui's functionality, ranging from UI components like checkboxes or text displays to abstract groupings of other widgets like a layout container or a html <div>. You will likely want to use pre-made widgets as well as creating your own.