Interactor(3I)
๐ Interactor โ the base class for interactive objects (that's Interactor(3I) bestie, from InterViews) ๐
โจ SYNOPSIS โจ
#include <InterViews/interactor.h>
๐ธ DESCRIPTION ๐ธ
Okay so back in 2.6, Interactor was THE base class for every single interactive object that ever existed. Nowadays? It's still here, just chilling, provided purely for backward compatibility. She's retired but she still shows up. Queen behaviour. ๐
Every interactor has a shape member variable, and that bad boy defines the desired characteristics of screen space in terms of size, shrinkability, and stretchability. This info is what gets used to allocate display space for the interactor, and then the interactor's canvas member variable gets set to the actual space obtained. The lower left corner of the canvas is addressed by (0, 0), and the upper right by the member variables (xmax, ymax). Simple as. ๐ฏ
The input member variable is the normal sensor for reading events. The output member variable is the standard painter for doing graphics operations. And listen โ interactors generally should NOT set output. It either gets inherited (and shared) from the interactor's parent, or it gets set by user customization attributes. Don't fight the system, bestie. ๐
โโ๏ธ
An interactor may optionally define the perspective member variable to represent the portion of total area that the interactor is displaying. Perspectives let interactors coordinate with other interactors โ think scrollers โ that wanna control the display area. Teamwork makes the dream work. ๐ซถ
An interactor also may specify certain characteristics of the interactor's canvas, like:
- whether it's read-only or read/write ๐
- whether its contents should be saved when not visible ๐พ
Interactors also may specify the visual format and interpretation of the input pointing device (e.g., mouse cursor) when it's inside the interactor's canvas. Cursor glow-up, fr fr. ๐ฑ๏ธโจ
To be mapped to some portion of the display, an interactor must have been inserted into a scene, called its parent. The interactor gets mapped when its parent is mapped. The root scene for the display can be accessed through a World(3I) object. It's giving family tree but make it pixels. ๐ณ
๐ CONSTRUCTORS ๐
Interactor()โ Construct an interactor. Theinputsensor andoutputpainters are initialized to nil. Fresh out the box, no thoughts, head empty. ๐ฃInteractor(const char* name)โ Construct an interactor associated with the string name. That string is used to customize the behavior of the interactor according to user preferences. Behaviour can also be customized on a per-class basis using the subclass name. And ngl, even though it's not explicitly documented: an instance of any object inheriting from interactor may be constructed with an additional argument (appearing first) containing the string name. For example, both of these are valid, no cap:
HGlue(natural, stretch)
HGlue("somename", natural, stretch)
~Interactor()โ The base destructor automatically deletes the base fields, includingshape,canvas,input, andoutput. She cleans up after herself. Self-care era. ๐งน๐
๐ CONFIGURATION ๐
void Align(Alignment, int w, int h, Coord& l, Coord& b)โ Return the coordinates at which an object with the given width and height will have the given alignment within the interactor's canvas. Math but make it cute. ๐void SetClassName(const char*)const char* GetClassName()void SetInstance(const char*)const char* GetInstance()โ Set/get the class or instance name for an interactor. These names are used to determine user style preferences. Heads up though:SetClassNameandSetInstancecan only be performed by subclasses. Sorry bestie, not everyone gets backstage access. ๐ซ๐๏ธvoid Config(Scene* s)โ Configure this interactor and its descendants according to user preferences. The scene s is assumed to be the interactor's parent and is used to inherit attribute values. You don't have to call this yourself โ it happens automatically when the ancestors of an interactor become known (e.g., when the interactor or an ancestor is inserted into a world). It's self-configuring, main character energy. โจ
Configuration involves a traversal of the interactor hierarchy. For each interactor in the hierarchy, the output painter is either inherited from its parent or copied from its parent if there are user preferences specific to the interactor for painter attributes such as colors, font, and brush.
Okay let's do the example because it's lowkey iconic. Suppose the user preference is:
A*B*font:9x15
and the interactor hierarchy is A.B.C.D (each . representing a nesting level in the hierarchy). Then:
- Interactors A and B will share the same output painter
- C will copy B's output and change the font to
9x15 - D will share C's output
See? The font change propagates down like gossip. ๐ฃ๏ธ๐ฌ
After assigning the output painter, configuration is performed recursively on any children interactors. The final step at each node in the traversal is to call the virtual Reconfig operation.
virtual void Reconfig()โ Perform any configuration specific to a particular interactor. This operation should minimally compute the interactor's shape based on the shape of its children and/or the characteristics of its output painter (e.g., font). It can also retrieve user preferences specific to this interactor's class or instance name usingGetAttribute. Do the bare minimum but do it well, honestly relatable. ๐const char* GetAttribute(const char*)โ Retrieve the value of a user preference with the given name.GetAttributesearches for the most specific match to the current context. It always finds the most relevant one, she's thorough like that. ๐virtual void Reshape(Shape&)Shape* GetShape()โ Set/get the shape of an interactor.Reshapeis a suggestion that an interactor's shape should change to the given one. The default operation sets the interactor's shape to the new shape and callsScene::Changeon the interactor's parent. > โ ๏ธ Suggested shape information may be lost when an interactor is configured โ so it's best to avoid use ofReshape. The same affect can usually be achieved by putting the interactor in a box along with a particular shape of glue. Don't waste your time on something that might ghost you. ๐void SetCursor(Cursor*)Cursor* GetCursor()โ Set/get the cursor that will be displayed when the pointing device is inside the interactor's canvas. If the interactor does not explicitly set its cursor, it will use its parent's cursor. In that case,GetCursorreturns nil. Inherited lewks, we love to see it. ๐
๐ฆ INTERACTOR HIERARCHY ๐ฆ
Scene* Parent()โ Return the interactor's parent, or nil if the interactor has not been inserted into a scene. Orphan era. ๐ญWorld* GetWorld()โ Return a pointer to the world the interactor has been inserted into, or nil if the interactor's root ancestor is not mapped.void GetRelative(Coord& x, Coord& y, Interactor* = nil)โ Map coordinates that are relative to this interactor's canvas to be relative to another interactor's canvas. If the other interactor is nil, then the coordinates are made relative to the world. Coordinate teleportation, but make it geometric. ๐virtual void GetComponents(Interactor**, int, Interactor**&, int&)โ Construct an array of pointers to the interactors contained within this interactor. The first and second parameters specify an array of interactors that is already allocated. This array is used if it is large enough โ otherwise a new array is allocated from free store. The third and fourth parameters return which array was used and the actual number of components. This operation is only defined by scenes; the default operation sets the number of elements to zero. Recycling when possible, allocating when necessary โ environmentally conscious queen. โป๏ธ๐
๐ฅ OUTPUT ๐ฅ
Canvas* GetCanvas() constโ Return the interactor's canvas, which may be nil if the interactor is not mapped to a display.ManagedWindow* GetTopLevelWindow() constโ Return the top-level window associated with the interactor, if it is mapped and top-level. Only for the ones at the top of the food chain. ๐virtual void Draw()โDrawis used to display the contents of an interactor, including the contents of any interior interactors. The defaultDrawoperation callsRedraw(0, 0, xmax, ymax). Interactors usually don't need to redefineDrawunless they contain interior interactors (i.e., scene subclasses) โ most simple interactors redefine onlyRedraw. Don't overthink it bestie, just redraw. ๐จvirtual void Highlight(boolean)โ Turn highlighting on or off, depending on whether the parameter istrueorfalse. The default operation is a nop. Literally does nothing. Relatable. ๐ซvoid SetCanvasType(CanvasType)CanvasType GetCanvasType()โ Set/get the type of canvas desired for an interactor. > โ ๏ธ This operation must be performed before an interactor is mapped. Timing is everything, periodt. โฐ
The possible canvas types are:
CanvasShapeOnlyโ meaning the interactor performs no input or output (e.g., glue)CanvasInputOnlyโ meaning the interactor performs no outputCanvasInputOutputโ which is the defaultCanvasSaveUnderโ which suggests that the interactor will be mapped for a short time (e.g., a popup menu) and that the information under the canvas should be savedCanvasSaveContentsโ which suggests thatRedrawcalls are expensive and should be avoided by caching the displayCanvasSaveBothโ which requests bothCanvasSaveUnderandCanvasSaveContents
Pick your fighter. ๐
void Sync()void Flush()โSyncwaits until any pending operations have completed.Flushmakes sure the local buffer of pending operations (if any) is sent to the display. An input operation will do aSyncautomatically if it would block โ thus, applications generally need not callSyncorFlushexplicitly. She handles it for you, you're welcome. ๐ซถ
๐ INPUT ๐
okay so input is literally the whole vibe of an interactor โ it's how it knows what's happening. let's get into it.
void Listen(Sensor*)โ when an interactor gets mapped onto a display, its input interest is determined by its input sensor. You can swap in a different sensor with theListenoperation. Wanna switch back to input? CallListen(input). periodt.void Read(Event&)boolean Read(long sec, long usec, Event&)โ every application has a single input queue of events. Any interactor can useReadto take the next event from the queue.RedrawandResizeoperations may be called as a side effect of aRead(or any input operation). Thetargetfield of the event specifies the interactor for which the event is intended, which is not necessarily the same as the interactor that performed theRead. The target is normally the interactor whose canvas is under the pointing device. The second form ofReadbehaves differently if there are no events to read: it times out after the given number of seconds and microseconds have elapsed and returnsfalseto the calling program. ๐ฐ๏ธvoid UnRead(Event&)โUnReadputs an event back on the input queue as if it had never been read. it's giving undo but for events ๐virtual void Handle(Event&)โ when an interactor wishes to pass an event to another interactor, it calls the other interactor'sHandleoperation. So input flow control can be either procedural withReador event-driven withHandle. choose your fighter โจvoid Run()โRunimplements a simple event dispatching loop. It callsReadto get the next event and passes the event to the target interactor viaHandle. The loop terminates if theHandleoperation sets the event'stargettonil. bye bestie ๐void QuitRunning(Event&)โQuitRunningsets the event'stargettonil. AHandleoperation can call it to makeRunexit its event dispatching loop. it's the emergency exit fr frboolean Check()โCheckdetermines whether an event of interest has occurred. ๐void Poll(Event&)โPollsets an event to reflect the current input state. Input polling can be wasteful of cycles and should be avoided if possible. > not me wasting cycles... ๐int CheckQueue()โCheckQueuereturns the number of input packets that have been queued within the application. The event queue manager always reads as much information as possible from input; thus, a singleReadmight store many events in a local buffer. Subsequent reads can simply access the buffer. This buffer can include out-of-band packets, such as those requiring aRedraw. The number returned byCheckQueuedoes not correspond, therefore, to the actual number of input events. so like, don't @ me if the math isn't mathing ๐งฎ
๐ฆ VIEWS ๐ฆ
virtual void Adjust(Perspective&)โAdjustsuggests to an interactor that its perspective should change to the given perspective; the interactor may choose to accept any part of the new perspective and must ensure that the parameter matches its (new) perspective before returning.Adjustcan be used by another interactor to scroll, pan, or zoom an interactor. it's giving gentle suggestion, not a demand ๐โโ๏ธPerspective* GetPerspective()โGetPerspectivereturns the perspective associated with an interactor ornilif the interactor has not assigned one. no perspective?nil. iconic.virtual void Update()โ change the display to reflect some change in state that the interactor depends on. This operation is used in a number of contexts. One example is in managing perspectives. If an interactor changes its perspective (e.g., the total of size of what it is displaying changes), it must notify its perspective, which in turn callsUpdateon the interactors that access the perspective (such as a scroller). the way that perspective gossip travels... ๐ซถ
๐ PROTECTED OPERATIONS ๐
virtual void Redraw(Coord l, Coord b, Coord r, Coord t)โ theRedrawoperation is called when some portion of theInteractorneeds to be redrawn, presumably because it was previously obscured. TheRedrawoperation should NOT redraw interior interactors; the Interviews library or theDrawoperation will call theirRedrawoperations automatically. The defaultRedrawoperation does nothing. > do NOT redraw interior interactors, bestie. let the library handle it. ๐ซvirtual void RedrawList(int n, Coord l[], Coord b[], Coord r[], Coord t[])โRedrawListnotifies an interactor that several areas of its canvas need to be redrawn, presumably because it was raised to the top of other canvases. The defaultRedrawListoperation redraws each area separately withRedraw. it's like a to-do list but for pixels โจvirtual void Resize()โResizenotifies an interactor that its canvas has been created or modified. Only scenes are typically concerned withResize, as they must place their component interactors within the new or resized canvas. The defaultResizeoperation does nothing. scenes stay busy ๐ฌ
๐ SEE ALSO ๐
InterViews Reference ManualPerspective(3I)Scene(3I)Sensor(3I)Shape(3I)World(3I)
k bye bestie ๐ this was from the InterViews Reference Manual, Interactor(3I) โ no date on this one, but you know the vibe. periodt. ๐
๐ฆ where this page comes from
- debian bookworm: ivtools-dev 2.0.11d.a1-1+b4
- debian trixie: ivtools-dev 2.0.11d.a1-3+b4
- ubuntu jammy: ivtools-dev 2.0.11d.a1-1build1
- ubuntu noble: ivtools-dev 2.0.11d.a1-3build1
- ubuntu questing: ivtools-dev 2.0.11d.a1-3build7
- ubuntu resolute: ivtools-dev 2.0.11d.a1-3build9
- ubuntu stonking: ivtools-dev 2.1.1+git.2025.07.26.a1-1 ยท MIT
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms