From cxwiki

UIElement forms the baseclass for all cxsource user interface components.

UIElement Hierarchy

UIElement* __nullable GetParent(void) const;
void AddChild(UIElement* __nullable child);
virtual UIElement* __nullable AddChild(UIElement* __nullable newChild, UIElement* __nullable insertBefore);
virtual void NotifyRemovingChild(UIElement* __nonnull child);
virtual void RemoveFromParent(void);
bool HasChildElement(UIElement* __nonnull element) const;
bool HasDescendantElement(const UIElement* __nullable element) const;
UIElement* __nullable GetChildByID(const CXString &uid);
UIElement* __nullable GetFirstChild(void) const; // the frontmost child
UIElement* __nullable GetLastChild(void) const; // the backmost child
UIElement* __nullable GetPrevSibling(void) const); // shallower (at least according to UICustomControlBase::DrawChildren();
UIElement* __nullable GetNextSibling(void) const); // deeper (at least according to UICustomControlBase::DrawChildren();


virtual void NotifyChildListChanged(void);


User Interface Implementations

Individual User Interface components often correspond with specific OS-provided native user interface controls, however this is not the only possible usage of the cxsource user interface system. UIElements can implement one of many possible behaviours, eg:
  • Native User Interface Control. Typically, a single native user interface is selected per build platform. This is often mandated by the host OS, but in some cases there may be multiple options available.
  • Custom User Interface Control. For example, a game may implement its own user-interface which exists as an overlay in a 3D-rendered view.
  • Generic User Interface Control. The components do not have hardcoded external dependencies and are compatible with any parent user interface.

To allow this flexibility, the cxsource user interface framework provides the concept of a "user interface implementation". At the most simple level, this is represented by objects of the UIAppearanceImplementation class. Each UIElement may be compatible with a single implementation, or multiple implementations, or even all implementations. In some scenarios, it may be possible to embed elements of one implementation under elements of a different implementation, in which case a special adapter element may be generated automatically to translate between the implementations.


The UIElement class itself is thread-agnostic. It is not reentrant, but does not make any assumptions about which thread is placing a call to any particular method. Derived classes may place additional limitations.

A given user interface hierarchy is effectively tied to a single thread. Once the UIElement is inserted into a user interface hierarchy, the user interface will typically be calling methods on the object quite regularly, which effectively ties the object to that user interface's thread. Some user interface implementations take this further, by mandating that:

  • The UIElement is only used from the thread that created it; or
  • The UIElement is only used from the application main thread.

Individual UIElement objects may also link into other thread-specific systems (such as CXTask) which will preclude them from being used on other threads safely.

As a result, the following guidelines are implicit when using UIElements:

  • Native User Interface components should only be created or accessed on the application main thread.
  • Any given custom User Interface component should be created and accessed on a single thread, which may or may not be the application main thread.



virtual ~UIElement(void);

virtual void Init(void);
virtual void Kill(void);
void KillChildren(void);


virtual void CreateSystemContext(void);

virtual void DestroySystemContext(void);

virtual void AttachToParentSystemContext(void);

virtual void DetachFromParentSystemContext(void);



virtual void SetVisibility(bool visible);

bool IsVisible(void) const;
virtual bool IsHierarchyVisible(void) const;
virtual bool IsAppearingActive(void) const;


virtual void NotifyChildVisibilityChanged(void);

virtual void NotifyHierarchyVisibilityChanged(bool bIsHierarchyVisible);




virtual void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom, BoundsAlignmentEnum hAlign = BOUNDS_FIXED, BoundsAlignmentEnum vAlign = BOUNDS_FIXED);
void SetSize(uint width, uint height);
Vector2i GetTopLeft(void) const;
sint32 GetWidth(void) const;
sint32 GetHeight(void) const;
Box2i GetLocalBounds(void);
Box2i GetBounds(void) const;

Box2i GetBaseBounds(void) const;
void SetUseAutomaticAlignment(bool bDoesUseAutomaticAlignment);
BoundsAlignmentEnum GetXAlign(void) const;
BoundsAlignmentEnum GetYAlign(void) const;
bool DoesUseAutomaticAlignment(void) const;

virtual void VirtualSizeChanged(void);

virtual bool ShouldTransmitBoundsChangeThroughEntireHierarchy(void) const;




virtual Vector2i GetOrigin(void) const;



virtual sint32 GetVirtualWidth(void) const;

virtual sint32 GetVirtualHeight(void) const;

void GetTerritory(sint32& o_width, sint32& o_height);

Coordinate Transforms

virtual Vector2i LocalToGlobalPoint(const Vector2i& point, const UIElement* __nullable useParent = nullptr) const;
virtual Vector2i GlobalToLocalPoint(const Vector2i& point, const UIElement* __nullable useParent = nullptr) const;
Box2i LocalToGlobalBox(const Box2i& box, const UIElement* __nullable useParent = nullptr) const;
Box2i GlobalToLocalBox(const Box2i& box, const UIElement* __nullable useParent = nullptr) const;



virtual sint32 GetElementMetric(MetricEnum metric, const Flags32& grafFlags = 0) const;



static void LockAutolayout(void);
static void UnlockAutolayout(void);
void ProcessAutolayout(const std::function<void(void)>& autoLayoutFunction);
static bool IsAutolayoutLocked(void);

void TriggerAutoAlignmentRefresh(void);


virtual void NotifyChildBoundsChanged(void);



virtual CXResultCode DispatchMessage(EventTargetEnum eventTargetEnum, const CXMessage& message);

virtual void SetKeyboardFocus(void);
virtual void ResignKeyboardFocus(void);

bool HasKeyboardFocus(void) const;

UIElement* __nullable GetChildAtPoint(const Vector2i& point) const;
UIElement* __nullable GetDescendantAtPoint(const Vector2i& point) const;


virtual void Scroll(const UICustomControlScrollEvent& event);
virtual void ScrollToBox(const Box2i& box);
bool GetBestVisibleBox(const Box2i& localBox, Box2i& o_bestVisibleBox) const;


virtual void Invalidate(void);
virtual void Invalidate(const Box2i&);
virtual void Invalidate(const CageRegion&);

Message Handling


See also "Focus" above.

void AddMessageHandler(const cx_function<CXResultCode(const CXMessage&)>& messageHandler);

virtual CXResultCode Message(const CXMessage &msg) override;