Chapter 37. Introduction

Index

Public and implementation objects
Implementing a custom widget

This is a guide for creating LibCXXW widgets with custom functionality, by taking the classes and templates the library uses to represent widgets and subclassing them. For typical use cases LibCXXW's widgets offer installable callbacks that provide sufficient functionality. These callbacks provide the means for executing actions in response to pointer and button clicks, and other activity and events. This is sufficient for most needs, but subclassing offers additional customization beyond that.

At this time, only the following widgets are fully exposed to the public API, and are subclassable:

x::w::element

A basic widget, that does nothing.

x::w::canvas

A little bit more than just an x::w::element. A widget with a fixed size, specified in millimeters, and actual size computed and updated based on the display's resolution and the current theme's scaling factor.

Subclasses can use the following mixin templates for inheriting common functionality:

x::w::background_color_elementObj

Defines one or more colors; based on the current theme and/or based on the widget's size (color gradients).

x::w::scratch_and_mask_buffer_draw

Implements a simplified interface for drawing the contents of the widget. Rather than updating only the rectangular areas of the widget that require updating, the entire contents of the widget get updated in one fell swoop.

x::w::focusable_elementObj

Adds support for handling keyboard focus and key press/release events.

x::w::container_elementObj

Creates an implementation class for a generic container.

x::w::focusframecontainer_elementObj

Creates a specialized container that draws a keyboard input focus frame around the container's contents whenever a widget in the container has keyboard input focus.

x::w::nonrecursive_visibilityObj

Overrides show_all() and hide_all() to make them equivalent to show() and hide().

x::w::always_visibleObj

This container becomes immediately visible. show_all() and hide_all() are ignored, but continue to get processed by the widgets in the container.

x::w::container_visible_elementObj

The entire container always gets scrolled into view instead of one widget in the container.

The desired properties inherited by a custom widgets are formed by combining these mixin templates. For example: x::w::nonrecursive_visibilityObj<x::w::container_elementObj<child_elementObj>>. This chapter gives a brief overview and examples of subclassing these widgets and using these mixins.

The most useful aspect of creating a custom class of LibCXXW's widgets is attaching some custom data to a widget in situations where the generic appdata object is not convenient. Implementing actions in response to pointer and button click events is also slightly faster than using the corresponding callbacks, but it takes more work.

Public and implementation objects

As described in the introductory tutorial all LibCXXW objects are reference-counted objects, represented by reference handles. Each LibCXXW widget consists of two objects. The public object is the object that's visible to the application, such as x::w::input_field. LibCXXW follows LibCXX's naming convention; and x::w::input_field is an x::ref to the x::w::input_fieldObj class. All other widget classes follow the same naming convention.

The public object (usually) has a reference to the second object, an internal implementation object. x::w::input_fieldObj::implObj is x::w::input_fieldObj's implementation class. This is the usual naming convention (with some isolated exceptions).

A brief, very brief, example of subclassing: the public object inherits from x::w::elementObj (x::w::elementObj implements shared functionality that's common to all widgets); and the implementation object is a subclass of x::w::elementObj::implObj.

But it turns out that only the main application window directly subclasses x::w::elementObj::implObj. All regular widgets are subclasses of x::w::child_elementObj. This class represents an implementation object for a widget in a container. All ordinary widgets always get placed inside some container and controlled by their container's layout manager. This results in all widgets using implementation objects that are subclasses of x::w::child_elementObj.