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

gfx/button_tracker.h

ButtonTracker: an analytics event every time a button is clicked.

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

Design notes

The reference's tracker listens to a button and logs a named event, with the button's on/off state added when it is a toggle. This is that, for the buttons here -- Button, IconButton, or anything else with an onClick -- and it sends nothing anywhere by itself: it calls Analytics::logEvent, which drops the event unless the plugin has added a destination (analytics.h says why that is the default).

How it attaches, and the two rules that follow

A button here has ONE onClick, a std::function, rather than a list of listeners. So the tracker wraps whatever onClick held when the tracker was constructed: the event is logged, then the previous handler runs.

Logged FIRST, deliberately. The click a plugin most wants to count is often the one whose handler closes something -- and a handler that destroys the button, or the panel holding the tracker, must be the last thing that runs. Nothing touches the button or the tracker after it.

Rule one: assign onClick BEFORE constructing the tracker. Assigning it afterwards replaces the wrapper, tracking stops, and nothing can notice.

Rule two is a non-rule: destroy the two in any order. The wrapper and the tracker share a small block of state; a destroyed tracker marks it inactive and the wrapper becomes a plain call to the previous handler. Destroying the tracker does NOT put the old onClick back, because "restore what was there" would also throw away any handler assigned since.

Types 1

Logs an analytics event on every click of one button, as the reference's class of the same name does. See the file comment for how it attaches and its one rule: set the button's onClick BEFORE constructing this.

Message thread, like the clicks it counts. The tracker keeps no pointer to the button, so the two may be destroyed in either order. Not copyable: a copy would share the wrapper's state, and its destructor would switch the original's tracking off.

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