Search guides and the APICtrl K
  1. API reference
  2. Native GUI

gfx/component_listeners.h

The hooks a component offers to things that are not it: listeners for its movement and its mouse events, a cached image to stand in for its painting, a target for dragged text, and an observer of every paint.

#include <sonore/gfx/component_listeners.h>
On this page

Design notes

Why these are a header of their own

They are interfaces component.h has to know -- Component calls into each of them -- and nothing else. Kept apart, the tree itself stays readable as the tree, and the machinery built on these (ComponentMovementWatcher, MouseInactivityDetector, StandardCachedComponentImage, the relative positioner, the text-drag dispatcher, ComponentPaintDiagnostics) is found by following one include rather than by reading the whole of component.h.

The lifetime rule they all share

Nothing here is owned by the component it is attached to, and either side may be destroyed first. The component keeps the list of what is attached to it and the listener keeps the list of what it is attached to; each side's destructor clears the other's entry. A caller that iterates listeners does so over a snapshot, checking each against the live list before calling it, and a detail::DeletionWatch tells it when the component itself has gone.

Types 5

Told when a component moves, shows, hides, changes parent or goes away.

The notification half of what the reference calls a ComponentListener, and the one piece the tree did not have: a component could react to its OWN resize (resized()) but nothing else could. ComponentMovementWatcher, the relative positioner and the text-drag dispatcher are all built on it.

The component does not own its listeners, and either side may go first: a listener destroyed while attached detaches itself, and a component destroyed while watched tells its listeners componentBeingDeleted and forgets them.

Sees the mouse events delivered to a component -- and, if asked, to everything inside it.

The router delivers an event to ONE component, the one under the pointer or the one holding capture. A listener is how something that is not that component hears it too: an inactivity detector watching a whole editor, a viewport scrolling when its content is dragged. Listeners are told BEFORE the component itself, so a listener cannot be starved by a handler that destroys the component it ran on.

A component's pixels, kept so it can be drawn again without being painted.

The interface; StandardCachedComponentImage below is the implementation setBufferedToImage installs. Owned by the component. paint() is called in place of the component's whole subtree being painted, with the Graphics already clipped to the component and translated into its coordinates.

Something that accepts TEXT dragged onto it -- from a field in the same editor, or from another application.

A component opts in by deriving from this as well and answering asTextDragAndDropTarget() with this -- the asWidget() pattern, because the SDK builds without RTTI. Internal drags reach it through the router's drag machinery (MouseRouter::startTextDrag); drags from outside reach it through a TextDragDispatcher that a platform's drop target drives.

Positions are in the receiving component's own coordinates.

Told about every component's paint, for as long as one is installed -- what ComponentPaintDiagnostics hangs on. Null by default, and then painting costs one pointer test per component.

↑↓ to move↵ to openEvery public name in the headers, and every guide