Class TCastleUserInterface
Unit
Declaration
type TCastleUserInterface = class(TCastleComponent)
Description
Basic user-interface class. All UI controls derive from this class, overriding chosen methods to react to some events.
Every control can have children controls, see Controls and ControlsCount. Parent control is recorded inside the Parent. A control may only be a child of one other control — that is, you cannot insert to the UI hierarchy the same control multiple times.
Control may handle mouse/keyboard input, see Press and Release methods.
Various methods return boolean saying if input event is handled. The idea is that not handled events are passed to the next control suitable. Handled events are generally not processed more — otherwise the same event could be handled by more than one listener, which is bad. Generally, return ExclusiveEvents if anything (possibly) was done (you changed any field value etc.) as a result of this, and only return False
when you're absolutely sure that nothing was done by this control.
Every control also has a position and size and takes some rectangular space on the container.
The position is controlled using the Anchor methods or anchor properties, like HorizontalAnchorSelf, HorizontalAnchorParent, HorizontalAnchorDelta. The size is controlled using the Width, WidthFraction, Height, HeightFraction, FullSize, or AutoSizeToChildren properties.
The size (before UI scaling is applied) can be queried using EffectiveWidth and EffectiveHeight methods. The rectangle where the control is visible (during rendering, after applying UI scaling) can be queried using RenderRect and RenderRectWithBorder methods.
Note that some descendants perform auto-sizing, that is: their effective size follows some natural property of the control. For example, TCastleLabel size by default follows the TCastleLabel.Caption value, and ignores the explicit size set in Width and Height. You can turn off auto-sizing by TCastleLabel.AutoSize, to manually control the size using Width and Height.
All the coordinates passed here should follow the Castle Game Engine convention that (0, 0) is left-bottom window corner.
Hierarchy
- TObject
- TPersistent
- TComponent
- TCastleComponent
- TCastleUserInterface
Overview
Fields
nested const DefaultWidth = 100.0; |
|
nested const DefaultHeight = 100.0; |
Methods
function ContainerWidth: Cardinal; virtual; |
|
function ContainerHeight: Cardinal; virtual; |
|
function ContainerRect: TRectangle; virtual; |
|
function ContainerSizeKnown: boolean; virtual; |
|
procedure DoCursorChange; virtual; deprecated 'better override VisibleChange and watch for chCursor in Changes'; |
|
procedure DefineProperties(Filer: TFiler); override; |
|
procedure UIScaleChanged; virtual; |
|
procedure PreferredSize(var PreferredWidth, PreferredHeight: Single); virtual; |
|
procedure BeforeSizing; virtual; |
|
procedure DoInternalMouseEnter; virtual; |
|
procedure DoInternalMouseLeave; virtual; |
|
function Theme: TCastleTheme; |
|
constructor Create(AOwner: TComponent); override; |
|
destructor Destroy; override; |
|
procedure CustomSerialization(const SerializationProcess: TSerializationProcess); override; |
|
function PropertySections(const PropertyName: String): TPropertySections; override; |
|
function GetEnumerator: TEnumerator; |
|
procedure InternalSetContainer(const Value: TCastleContainer); virtual; |
|
function Press(const Event: TInputPressRelease): boolean; virtual; |
|
function Release(const Event: TInputPressRelease): boolean; virtual; |
|
function PreviewPress(const Event: TInputPressRelease): boolean; virtual; |
|
function PreviewRelease(const Event: TInputPressRelease): boolean; virtual; |
|
function Motion(const Event: TInputMotion): boolean; virtual; |
|
function SensorRotation(const X, Y, Z, Angle: Double; const SecondsPassed: Single): boolean; virtual; |
|
function SensorTranslation(const X, Y, Z, Length: Double; const SecondsPassed: Single): boolean; virtual; |
|
function JoyAxisMove(const JoyID, Axis: Byte): boolean; virtual; deprecated 'use event Joysticks.OnAxisMove, or just observe Joysticks[0].Axis'; |
|
function JoyButtonPress(const JoyID, Button: Byte): boolean; virtual; deprecated 'use Joysticks.OnButtonDown or Joysticks.OnButtonPress'; |
|
procedure Update(const SecondsPassed: Single; var HandleInput: boolean); virtual; |
|
procedure VisibleChange(const Changes: TCastleUserInterfaceChanges; const ChangeInitiatedByChildren: boolean = false); overload; virtual; |
|
function AllowSuspendForInput: boolean; virtual; |
|
procedure Resize; virtual; |
|
procedure ContainerResize(const AContainerWidth, AContainerHeight: Cardinal); virtual; deprecated 'use Resize'; |
|
function ControlsCount: Integer; |
|
procedure InsertFront(const NewItem: TCastleUserInterface); overload; |
|
procedure InsertFrontIfNotExists(const NewItem: TCastleUserInterface); |
|
procedure InsertFront(const NewItems: TCastleUserInterfaceList); overload; |
|
procedure InsertBack(const NewItem: TCastleUserInterface); overload; |
|
procedure InsertBackIfNotExists(const NewItem: TCastleUserInterface); |
|
procedure InsertBack(const NewItems: TCastleUserInterfaceList); overload; |
|
procedure InsertControl(const Index: Integer; const NewItem: TCastleUserInterface); |
|
procedure RemoveControl(const Item: TCastleUserInterface); |
|
function IndexOfControl(const Item: TCastleUserInterface): Integer; |
|
procedure ClearControls; |
|
function CapturesEventsAtPosition(const Position: TVector2): boolean; virtual; |
|
procedure BeforeRender; virtual; |
|
procedure Render; virtual; |
|
procedure RenderOverChildren; virtual; |
|
function TooltipExists: Boolean; virtual; |
|
procedure TooltipRender(const TooltipPosition: TVector2); virtual; |
|
procedure GLContextOpen; virtual; |
|
procedure GLContextClose; virtual; |
|
procedure SetFocused(const Value: boolean); virtual; |
|
function EffectiveRect: TFloatRectangle; |
|
function EffectiveWidth: Single; |
|
function EffectiveHeight: Single; |
|
function EffectiveWidthForChildren: Single; |
|
function EffectiveHeightForChildren: Single; |
|
function CalculatedWidth: Cardinal; deprecated 'use EffectiveWidth'; |
|
function CalculatedHeight: Cardinal; deprecated 'use EffectiveHeight'; |
|
function CalculatedRect: TRectangle; deprecated 'use EffectiveRect'; |
|
function RenderRect: TFloatRectangle; |
|
function RenderRectWithBorder: TFloatRectangle; |
|
function ScreenRect: TRectangle; deprecated 'use RenderRect'; |
|
function ContainerToLocalPosition(ContainerPosition: TVector2; const ContainerPositionScaled: Boolean = true): TVector2; |
|
function LocalToContainerPosition(const LocalPosition: TVector2; const ContainerPositionScaled: Boolean = true): TVector2; |
|
function ParentRect: TFloatRectangle; |
|
procedure Anchor(const AHorizontalAnchor: THorizontalPosition; const AHorizontalAnchorDelta: Single = 0); overload; |
|
procedure Anchor( const AHorizontalAnchorSelf, AHorizontalAnchorParent: THorizontalPosition; const AHorizontalAnchorDelta: Single = 0); overload; |
|
procedure Anchor(const AVerticalAnchor: TVerticalPosition; const AVerticalAnchorDelta: Single = 0); overload; |
|
procedure Anchor( const AVerticalAnchorSelf, AVerticalAnchorParent: TVerticalPosition; const AVerticalAnchorDelta: Single = 0); overload; |
|
procedure AlignHorizontal( const ControlPosition: TPositionRelative = prMiddle; const ContainerPosition: TPositionRelative = prMiddle; const X: Single = 0); deprecated 'use Anchor'; |
|
procedure Align( const ControlPosition: THorizontalPosition; const ContainerPosition: THorizontalPosition; const X: Single = 0); overload; deprecated 'use Anchor'; |
|
procedure AlignVertical( const ControlPosition: TPositionRelative = prMiddle; const ContainerPosition: TPositionRelative = prMiddle; const Y: Single = 0); deprecated 'use Anchor'; |
|
procedure Align( const ControlPosition: TVerticalPosition; const ContainerPosition: TVerticalPosition; const Y: Single = 0); overload; deprecated 'use Anchor'; |
|
procedure Center; deprecated 'use Anchor(hpMiddle); Anchor(vpMiddle); to reliably center the control'; |
|
function UIScale: Single; virtual; |
|
procedure EditorAllowResize(out ResizeWidth, ResizeHeight: Boolean; out Reason: String); virtual; |
Properties
property OnVisibleChange: TCastleUserInterfaceChangeEvent
read FOnVisibleChange write FOnVisibleChange; |
|
property Container: TCastleContainer read FContainer; |
|
property OnCursorChange: TNotifyEvent
read FOnCursorChange write FOnCursorChange; deprecated 'use OnVisibleChange (or override VisibleChange) and watch for Changes that include chCursor'; |
|
property ExclusiveEvents: boolean
read FExclusiveEvents write FExclusiveEvents default true; |
|
property Controls [constIndex:Integer]: TCastleUserInterface read GetControls write SetControls; |
|
property GetExists: Boolean read FExists; deprecated 'use Exists'; |
|
property GLInitialized: boolean read FGLInitialized default false; |
|
property Focused: boolean read FFocused write SetFocused; |
|
property Parent: TCastleUserInterface read FParent; |
|
property FloatWidth: Single read FWidth write SetWidth stored false; deprecated 'use Width'; |
|
property FloatHeight: Single read FHeight write SetHeight stored false; deprecated 'use Height'; |
|
property AnchorDelta: TVector2 read GetAnchorDelta write SetAnchorDelta; |
|
property KeepInFront: boolean read FKeepInFront write FKeepInFront
default false; |
|
property BorderColor: TCastleColor read FBorderColor write SetBorderColor; |
|
property HasHorizontalAnchor: boolean
read FHasHorizontalAnchor write FHasHorizontalAnchor stored false; deprecated 'this property does not do anything anymore, anchors are always active'; |
|
property HasVerticalAnchor: boolean
read FHasVerticalAnchor write FHasVerticalAnchor stored false; deprecated 'this property does not do anything anymore, anchors are always active'; |
|
property Visible: Boolean read FVisible; |
|
property EnableUIScaling: boolean
read FEnableUIScaling write SetEnableUIScaling default true; |
|
property CapturesEvents: boolean read FCapturesEvents write FCapturesEvents
default true; |
|
property OnInternalMouseEnter: TUiNotifyEvent
read FOnInternalMouseEnter write FOnInternalMouseEnter; |
|
property OnInternalMouseLeave: TUiNotifyEvent
read FOnInternalMouseLeave write FOnInternalMouseLeave; |
|
property Cursor: TMouseCursor read FCursor write SetCursor default mcDefault; |
|
property OnUpdate: TUiUpdateEvent read FOnUpdate write FOnUpdate; |
|
property OnPress: TUiPressReleaseEvent read FOnPress write FOnPress; |
|
property OnRelease: TUiPressReleaseEvent read FOnRelease write FOnRelease; |
|
property OnMotion: TUiMotionEvent read FOnMotion write FOnMotion; |
|
property OnRender: TUiNotifyEvent read FOnRender write FOnRender; |
|
property Exists: boolean read FExists write SetExists default true; |
|
property Left: Single read FLeft write SetLeft stored false default 0; |
|
property Bottom: Single read FBottom write SetBottom default 0; |
|
property FullSize: boolean read FFullSize write SetFullSize default false; |
|
property Width: Single read FWidth write SetWidth default DefaultWidth; |
|
property Height: Single read FHeight write SetHeight default DefaultHeight; |
|
property WidthFraction: Single read FWidthFraction write SetWidthFraction default 0.0; |
|
property HeightFraction: Single read FHeightFraction write SetHeightFraction default 0.0; |
|
property AutoSizeToChildren: Boolean
read FAutoSizeToChildren write SetAutoSizeToChildren default false; |
|
property AutoSizeToChildrenPaddingRight: Single
read FAutoSizeToChildrenPaddingRight
write SetAutoSizeToChildrenPaddingRight default 0; |
|
property AutoSizeToChildrenPaddingTop: Single
read FAutoSizeToChildrenPaddingTop
write SetAutoSizeToChildrenPaddingTop default 0; |
|
property HorizontalAnchorSelf: THorizontalPosition
read FHorizontalAnchorSelf write SetHorizontalAnchorSelf default hpLeft; |
|
property HorizontalAnchorParent: THorizontalPosition
read FHorizontalAnchorParent write SetHorizontalAnchorParent default hpLeft; |
|
property HorizontalAnchorDelta: Single
read FHorizontalAnchorDelta write SetHorizontalAnchorDelta default 0; |
|
property VerticalAnchorSelf: TVerticalPosition
read FVerticalAnchorSelf write SetVerticalAnchorSelf default vpBottom; |
|
property VerticalAnchorParent: TVerticalPosition
read FVerticalAnchorParent write SetVerticalAnchorParent default vpBottom; |
|
property VerticalAnchorDelta: Single
read FVerticalAnchorDelta write SetVerticalAnchorDelta default 0; |
|
property Culling: Boolean read FCulling write SetCulling default false; |
|
property ClipChildren: Boolean read FClipChildren write SetClipChildren default false; |
|
property Border: TBorder read FBorder; |
|
property CustomTheme: TCastleTheme read FCustomTheme write SetCustomTheme; |
|
property BorderColorPersistent: TCastleColorPersistent read FBorderColorPersistent ; |
Description
Fields
nested const DefaultWidth = 100.0; |
|
nested const DefaultHeight = 100.0; |
|
Methods
function ContainerWidth: Cardinal; virtual; |
|
Container sizes. |
function ContainerHeight: Cardinal; virtual; |
|
function ContainerRect: TRectangle; virtual; |
|
function ContainerSizeKnown: boolean; virtual; |
|
procedure DoCursorChange; virtual; deprecated 'better override VisibleChange and watch for chCursor in Changes'; |
|
Warning: this symbol is deprecated: better override VisibleChange and watch for chCursor in Changes Called when Cursor changed. In TCastleUserInterface class, just calls OnCursorChange. |
procedure DefineProperties(Filer: TFiler); override; |
|
procedure UIScaleChanged; virtual; |
|
procedure PreferredSize(var PreferredWidth, PreferredHeight: Single); virtual; |
|
Controls that have a preferred size should override this. By default this contains values derived from Width, WidthFraction, Height, HeightFraction, with Border subtracted. Note that the arguments should be already scaled, i.e. multiplied by UIScale, i.e. expressed in final device pixels. Note that the returned PreferredWidth and PreferredHeight must not include the space for Border. Border size will be added later. |
procedure BeforeSizing; virtual; |
|
Called right before calculating size. This is your only chance to adjust e.g. children size, if you need them to be synchronized with something, and you may use AutoSizeToChildren. In most use-cases, you rather adjust preferred size by overriding PreferredSize. |
procedure DoInternalMouseEnter; virtual; |
|
procedure DoInternalMouseLeave; virtual; |
|
function Theme: TCastleTheme; |
|
Theme that should be used by this control. Either CustomTheme or global Theme. |
constructor Create(AOwner: TComponent); override; |
|
destructor Destroy; override; |
|
procedure CustomSerialization(const SerializationProcess: TSerializationProcess); override; |
|
function PropertySections(const PropertyName: String): TPropertySections; override; |
|
function GetEnumerator: TEnumerator; |
|
procedure InternalSetContainer(const Value: TCastleContainer); virtual; |
|
function Press(const Event: TInputPressRelease): boolean; virtual; |
|
Handle press or release of a key, mouse button or mouse wheel. Return When implementing in descendants it is best to override it like this: function TMyControl.Press(const Event: TInputPressRelease): boolean; begin Result := inherited; if Result then Exit; // exit if ancestor already handled event if Event.IsKey(keyEnter) then begin // do something in reaction on Enter Exit(ExclusiveEvents); // ExclusiveEvents is true by default end; if Event.IsMouseButton(buttonLeft) then begin // do something in reaction on Enter Exit(ExclusiveEvents); // ExclusiveEvents is true by default end; end;
Note that releasing of the mouse wheel is not reported now by any backend. Only releasing of keys and mouse buttons is reported. The events PreviewPress and PreviewRelease are passed first to the parent control, before children have a chance to process this event. Overriding them makes sense if you draw something in TCastleUserInterface.RenderOverChildren. The events Press and Release are passed to the parent only after the children had a chance to process this event. Overriding them makes sense if you draw something in TCastleUserInterface.Render. This is usually more natural, and adviced. |
function Release(const Event: TInputPressRelease): boolean; virtual; |
|
function PreviewPress(const Event: TInputPressRelease): boolean; virtual; |
|
function PreviewRelease(const Event: TInputPressRelease): boolean; virtual; |
|
function Motion(const Event: TInputMotion): boolean; virtual; |
|
|
function SensorRotation(const X, Y, Z, Angle: Double; const SecondsPassed: Single): boolean; virtual; |
|
Rotation detected by 3D sensor. Used for example by 3Dconnexion devices.
Parameters
|
function SensorTranslation(const X, Y, Z, Length: Double; const SecondsPassed: Single): boolean; virtual; |
|
Translation detected by 3D sensor. Used for example by 3Dconnexion devices.
Parameters
|
procedure Update(const SecondsPassed: Single; var HandleInput: boolean); virtual; |
|
Control may do here anything that must be continuously repeated. E.g. camera handles here falling down due to gravity, rotating model in Examine mode, and many more.
This method may be used, among many other things, to continuously react to the fact that user pressed some key (or mouse button). For example, if holding some key should move some 3D object, you should do something like: if HandleInput then begin if Container.Pressed[keyArrowRight] then Transform.Position := Transform.Position + Vector3(SecondsPassed * 10, 0, 0); HandleInput := not ExclusiveEvents; end;
Instead of directly using a key code, consider also using TInputShortcut that makes the input key nicely configurable. See engine tutorial about handling inputs. Multiplying movement by SecondsPassed makes your operation frame-rate independent. Object will move by 10 units in a second, regardless of how many FPS your game has. The code related to HandleInput is important if you write a generally-useful control that should nicely cooperate with all other controls, even when placed on top of them or under them. The correct approach is to only look at pressed keys/mouse buttons if HandleInput is Note that to handle a single press / release (like "switch light on when pressing a key") you should rather use Press and Release methods. Use this method only for continuous handling (like "holding this key makes the light brighter and brighter"). To understand why such HandleInput approach is needed, realize that the "Update" events are called differently than simple mouse and key events like "Press" and "Release". "Press" and "Release" events return whether the event was somehow "handled", and the container passes them only to the controls under the mouse (decided by TCastleUserInterface.CapturesEventsAtPosition). And as soon as some control says it "handled" the event, other controls (even if under the mouse) will not receive the event. This approach is not suitable for Update events. Some controls need to do the Update job all the time, regardless of whether the control is under the mouse and regardless of what other controls already did. So all controls (well, all controls that exist, in case of TCastleUserInterface, see TCastleUserInterface.Exists) receive Update calls. So the "handled" status is passed through HandleInput. If a control is not under the mouse, it will receive HandleInput = Parameters
|
procedure VisibleChange(const Changes: TCastleUserInterfaceChanges; const ChangeInitiatedByChildren: boolean = false); overload; virtual; |
|
Called always when something important inside this control (or it's children) changed. To be more precise, this is called when something mentioned among the TCastleUserInterfaceChange enumerated items changed. This is always called with Changes <> [] (non-empty set). |
function AllowSuspendForInput: boolean; virtual; |
|
Allow window containing this control to suspend waiting for user input. Typically you want to override this to return In this class, this simply returns always See also
|
procedure Resize; virtual; |
|
Event called when the container (component or window with OpenGL context) size changes. You can resize/reposition your component here, for example set TCastleUserInterface.Left or TCastleUserInterface.Bottom, to react to parent size changes. This is called only when the OpenGL context of the container is initialized, so you can be sure that this is called only between GLContextOpen and GLContextClose. We also call this once when inserting into the controls list (like TCastleWindow.Controls or TCastleControl.Controls or inside parent TCastleUserInterface), if inserting into the container/parent with already initialized OpenGL context. If inserting into the container/parent without OpenGL context initialized, it will be called later, when OpenGL context will get initialized, right after GLContextOpen. In other words, this is always called to let the control know the size of the container, if and only if the OpenGL context is initialized. |
procedure ContainerResize(const AContainerWidth, AContainerHeight: Cardinal); virtual; deprecated 'use Resize'; |
|
Warning: this symbol is deprecated: use Resize |
function ControlsCount: Integer; |
|
procedure InsertFront(const NewItem: TCastleUserInterface); overload; |
|
Add child control, at the front of other children. |
procedure InsertFrontIfNotExists(const NewItem: TCastleUserInterface); |
|
procedure InsertFront(const NewItems: TCastleUserInterfaceList); overload; |
|
procedure InsertBack(const NewItem: TCastleUserInterface); overload; |
|
Add child control, at the back of other children. |
procedure InsertBackIfNotExists(const NewItem: TCastleUserInterface); |
|
procedure InsertBack(const NewItems: TCastleUserInterfaceList); overload; |
|
procedure InsertControl(const Index: Integer; const NewItem: TCastleUserInterface); |
|
Add child control at specified position. It is usually easier to use InsertFront or InsertBack, if possible. |
procedure RemoveControl(const Item: TCastleUserInterface); |
|
Remove control added by InsertFront or InsertBack. Note that this method does not free the Item instance. This method merely removes Item from our controls, so that Item is no longer rendered as part of this parent. It is still the caller's responsibility to make sure the Item is freed at some point. See https://castle-engine.io/modern_pascal_introduction.html#_freeing_classes for description how to free instances in Pascal. As TCastleUserInterface descends from TComponent, a simple and proper solution is often just to create it with some "owner" (like TUIState.FreeAtStop or Application) that will take care of freeing it. |
function IndexOfControl(const Item: TCastleUserInterface): Integer; |
|
Index of child control, or -1 if not present. |
procedure ClearControls; |
|
Remove all child controls added by InsertFront or InsertBack. Note that, just like RemoveControl, this method does not free the children controls. This method merely removes children controls, so they are no longer rendered as part of the parent. It is still the caller's responsibility to make sure the children controls are freed at some point. See https://castle-engine.io/modern_pascal_introduction.html#_freeing_classes for description how to free instances in Pascal. As TCastleUserInterface descends from TComponent, a simple and proper solution is often just to create it with some "owner" (like TUIState.FreeAtStop or Application) that will take care of freeing it. |
function CapturesEventsAtPosition(const Position: TVector2): boolean; virtual; |
|
Does this control capture events under this container position. The default implementation simply checks whether Position is inside RenderRect. It also checks whether CapturesEvents is Always treated like |
procedure BeforeRender; virtual; |
|
Prepare your resources, right before drawing. Called only when Exists and GLInitialized. Do not explicitly call this method. Instead, render controls by adding them to the TCastleContainer.Controls list, or render them explicitly (for off-screen rendering) by TCastleContainer.RenderControl. |
procedure Render; virtual; |
|
Render a control. Called only when Exists and GLInitialized, you can depend on it in the implementation of this method. Do not explicitly call this method. Instead, render controls by adding them to the TCastleContainer.Controls list, or render them explicitly (for off-screen rendering) by TCastleContainer.RenderControl. This is method should only be overridden in your own code. Before calling this method we always set some OpenGL state, and you can depend on it (and you can carelessly change it, as it will be reset again before rendering other control). OpenGL state always set:
Beware that GLSL RenderContext.CurrentProgram has undefined value when this is called. You should always set it, before making direct OpenGL drawing calls (all the engine drawing routines of course do it already, this is only a concern if you make direct OpenGL / OpenGLES calls). |
procedure RenderOverChildren; virtual; |
|
Render a control contents over the children controls. This is analogous to Render, but it executes after children are drawn. You should usually prefer to override Render instead of this method, as the convention is that the parent is underneath children. |
function TooltipExists: Boolean; virtual; |
|
Render a tooltip of this control. If you want to have tooltip for this control detected, you have to override TooltipRender is called in the same way as Render. TooltipRender is always called as a last (front-most) control. Argument TooltipPosition is the left-bottom (in screen space, regardless of UIScaling) suggested position of the tooltip. It is simplest to descend from TCastleUserInterfaceFont, that implements simple TCastleUserInterfaceFont.Tooltip property and overrides these two methods as necessary. |
procedure TooltipRender(const TooltipPosition: TVector2); virtual; |
|
procedure GLContextClose; virtual; |
|
Destroy your OpenGL resources. Called when OpenGL context of the container is destroyed. Also called when controls is removed from the container You should release here any resources that are tied to the OpenGL context. In particular, the ones created in GLContextOpen. As an exception, this is called regardless of the Exists value. This way a control can release it's resources, regardless if it exists now. |
procedure SetFocused(const Value: boolean); virtual; |
|
Called when this control becomes or stops being focused, that is: under the mouse cursor and will receive events. This updates Focused property. This also calls OnInternalMouseEnter / OnInternalMouseLeave. |
function EffectiveRect: TFloatRectangle; |
|
Control position and size. Use this to base other controls size/position on this control's calculated size/position. The algorithm that determines control position and size is like this:
The above describes the size of the content and border, summed. The content itself may be a little smaller, when the Border is used. The size of the "content itself" is returned only by The anchors (see Anchor) also affect the final position of the control. Note that some descendants do auto-sizing by default. This means that some of these properties may be ignored, and instead the calculated size (EffectiveWidth, EffectiveHeight) depends on some core values of the control. For example:
Consult the documentation of each descendant for the exact specification of the size behavior. This method returns the rectangle in local coordinates (relative to the parent 2D control). The returned rectangle size includes the border size. The returned rectangle size uses "unscaled" coordinates, which means that they correspond to the sizes you set e.g. in TCastleUserInterface.Width, TCastleUserInterface.Height, and translation units you use with e.g. TCastleUserInterface.Anchor. If you're looking for a way to query the size of the control in final scaled coordinates (in real device pixels), and not relative to the parent position, use RenderRect or RenderRectWithBorder instead. This method ignores the current value of the Exists method and Exists property, that is: the result of this function assumes that control does exist.
See also
|
function EffectiveWidth: Single; |
|
Calculated width of the control, without UI scaling. Useful if you want to base other controls size/position on this control calculated size. Unlike the Width property, this is the effective size, not the desired size. So this is already processed by any auto-sizing mechanism (e.g. TCastleImageControl may adjust it's own size to the underlying image, depending on settings), it is changed by FullSize and so on. It is always equal to just See also
|
function EffectiveHeight: Single; |
|
Calculated height of the control, without UI scaling. Useful if you want to base other controls size/position on this control calculated size. Unlike the Height property, this is the effective size, not the desired size. So this is already processed by any auto-sizing mechanism (e.g. TCastleImageControl may adjust it's own size to the underlying image, depending on settings), it is changed by FullSize and so on. It is always equal to just See also
|
function EffectiveWidthForChildren: Single; |
|
EffectiveWidth without Border size. |
function EffectiveHeightForChildren: Single; |
|
EffectiveHeight without Border size. |
function CalculatedWidth: Cardinal; deprecated 'use EffectiveWidth'; |
|
Warning: this symbol is deprecated: use EffectiveWidth |
function CalculatedHeight: Cardinal; deprecated 'use EffectiveHeight'; |
|
Warning: this symbol is deprecated: use EffectiveHeight |
function CalculatedRect: TRectangle; deprecated 'use EffectiveRect'; |
|
Warning: this symbol is deprecated: use EffectiveRect |
function RenderRect: TFloatRectangle; |
|
Position and size of this control, assuming it exists, in container coordinates (in final device pixels). The primary use of this is inside Render. A proper UI control should adjust to draw precisely in this rectangle. |
function RenderRectWithBorder: TFloatRectangle; |
|
function ScreenRect: TRectangle; deprecated 'use RenderRect'; |
|
Warning: this symbol is deprecated: use RenderRect |
function ContainerToLocalPosition(ContainerPosition: TVector2; const ContainerPositionScaled: Boolean = true): TVector2; |
|
Convert position relative to container (in final device coordinates, without UI scaling, by default) into position relative to this UI control (in coordinates with UI scaling). Useful e.g. to convert mouse/touch position from TInputPressRelease.Position into position useful for children of this UI control. The exact definition is that using the result of this to set our child AnchorDelta, assuming the child is anchored to the left-bottom (the default state) and child has Left = Bottom = 0, sets child position exactly to the indicated point on the container. Parameters
|
function LocalToContainerPosition(const LocalPosition: TVector2; const ContainerPositionScaled: Boolean = true): TVector2; |
|
Convert position relative to this UI control (in coordinates with UI scaling) into relative to container (in final device coordinates, without UI scaling, by default). Reverses ContainerToLocalPosition. Parameters
|
function ParentRect: TFloatRectangle; |
|
Rectangle filling the parent control (or container), in local coordinates. Since this is in local coordinates, the returned rectangle Left and Bottom are always zero, unless parent has Border (the returned rectangle is shrunk by Parent.Border). This is already scaled by UI scaling. |
procedure Anchor(const AHorizontalAnchor: THorizontalPosition; const AHorizontalAnchorDelta: Single = 0); overload; |
|
Quick way to enable horizontal anchor, to automatically keep this control aligned to parent. Sets HorizontalAnchorSelf, HorizontalAnchorParent, HorizontalAnchorDelta. |
procedure Anchor( const AHorizontalAnchorSelf, AHorizontalAnchorParent: THorizontalPosition; const AHorizontalAnchorDelta: Single = 0); overload; |
|
Quick way to enable horizontal anchor, to automatically keep this control aligned to parent. Sets HorizontalAnchorSelf, HorizontalAnchorParent, HorizontalAnchorDelta. |
procedure Anchor(const AVerticalAnchor: TVerticalPosition; const AVerticalAnchorDelta: Single = 0); overload; |
|
Quick way to enable vertical anchor, to automatically keep this control aligned to parent. Sets VerticalAnchorSelf, VerticalAnchorParent, VerticalAnchorDelta. |
procedure Anchor( const AVerticalAnchorSelf, AVerticalAnchorParent: TVerticalPosition; const AVerticalAnchorDelta: Single = 0); overload; |
|
Quick way to enable vertical anchor, to automatically keep this control aligned to parent. Sets VerticalAnchorSelf, VerticalAnchorParent, VerticalAnchorDelta. |
procedure AlignHorizontal( const ControlPosition: TPositionRelative = prMiddle; const ContainerPosition: TPositionRelative = prMiddle; const X: Single = 0); deprecated 'use Anchor'; |
|
Warning: this symbol is deprecated: use Anchor Immediately position the control with respect to the parent by adjusting Left. Deprecated, use Align with THorizontalPosition. |
procedure Align( const ControlPosition: THorizontalPosition; const ContainerPosition: THorizontalPosition; const X: Single = 0); overload; deprecated 'use Anchor'; |
|
Warning: this symbol is deprecated: use Anchor Immediately position the control with respect to the parent by adjusting Left. Note that using Anchor is often more comfortable than this method, since you only need to set anchor once (for example, right after creating the control). In contract, adjusting position using this method will typically need to be repeated at each window on resize, like in TCastleWindow.OnResize. |
procedure AlignVertical( const ControlPosition: TPositionRelative = prMiddle; const ContainerPosition: TPositionRelative = prMiddle; const Y: Single = 0); deprecated 'use Anchor'; |
|
Warning: this symbol is deprecated: use Anchor Immediately position the control with respect to the parent by adjusting Bottom. Deprecated, use Align with TVerticalPosition. |
procedure Align( const ControlPosition: TVerticalPosition; const ContainerPosition: TVerticalPosition; const Y: Single = 0); overload; deprecated 'use Anchor'; |
|
Warning: this symbol is deprecated: use Anchor Immediately position the control with respect to the parent by adjusting Bottom. Note that using Anchor is often more comfortable than this method, since you only need to set anchor once (for example, right after creating the control). In contract, adjusting position using this method will typically need to be repeated at each window on resize, like in TCastleWindow.OnResize. |
procedure Center; deprecated 'use Anchor(hpMiddle); Anchor(vpMiddle); to reliably center the control'; |
|
Warning: this symbol is deprecated: use Anchor(hpMiddle); Anchor(vpMiddle); to reliably center the control Immediately center the control within the parent, both horizontally and vertically. Note that using Anchor is often more comfortable than this method, since you only need to set anchor once. For example, right after creating the control call |
function UIScale: Single; virtual; |
|
UI scale of this control, derived from container (see TCastleContainer.UIScaling and EnableUIScaling). |
procedure EditorAllowResize(out ResizeWidth, ResizeHeight: Boolean; out Reason: String); virtual; |
|
Override this to prevent resizing some dimension in CGE editor. |
Properties
property OnVisibleChange: TCastleUserInterfaceChangeEvent
read FOnVisibleChange write FOnVisibleChange; |
|
Called always when something important inside this control (or it's children) changed. See VisibleChange for details about when and how this is called. Be careful when handling this event. Various changes may cause this, so be prepared to handle it at any moment, even in the middle when UI control is changing. It may also occur very often. It's usually safest to only set a boolean flag like "something should be recalculated" when this event happens, and do the actual recalculation later. |
property Container: TCastleContainer read FContainer; |
|
Container of this control. When adding control to container's Controls list (like TCastleWindow.Controls) container will automatically set itself here, and when removing from container this will be changed back to May be |
property OnCursorChange: TNotifyEvent
read FOnCursorChange write FOnCursorChange; deprecated 'use OnVisibleChange (or override VisibleChange) and watch for Changes that include chCursor'; |
|
Warning: this symbol is deprecated: use OnVisibleChange (or override VisibleChange) and watch for Changes that include chCursor Event called when the Cursor property changes. This event is, in normal circumstances, used by the Container, so you should not use it in your own programs. |
property Controls [constIndex:Integer]: TCastleUserInterface read GetControls write SetControls; |
|
property GetExists: Boolean read FExists; deprecated 'use Exists'; |
|
Warning: this symbol is deprecated: use Exists |
property GLInitialized: boolean read FGLInitialized default false; |
|
property Focused: boolean read FFocused write SetFocused; |
|
See SetFocused. |
property Parent: TCastleUserInterface read FParent; |
|
Visual parent control. This control is rendered within the parent, and it's anchors and coordinates are relative to the parent. Parent may be |
property FloatWidth: Single read FWidth write SetWidth stored false; deprecated 'use Width'; |
|
Warning: this symbol is deprecated: use Width |
property FloatHeight: Single read FHeight write SetHeight stored false; deprecated 'use Height'; |
|
Warning: this symbol is deprecated: use Height |
property AnchorDelta: TVector2 read GetAnchorDelta write SetAnchorDelta; |
|
A simple shortcut to modify HorizontalAnchorDelta/VerticalAnchorDelta as TVector2 |
property BorderColor: TCastleColor read FBorderColor write SetBorderColor; |
|
Color of the Border, by default completely transparent black. |
property Visible: Boolean read FVisible; |
|
Is the control possibly visible. This is always |
property EnableUIScaling: boolean
read FEnableUIScaling write SetEnableUIScaling default true; |
|
Enable or disable UI scaling for this particular control. See more about UI scaling on TCastleContainer.UIScaling and TCastleUserInterface.UIScale. Setting this to Note that this does not work recursively, i.e. it does not affect the children of this control. Setting this to The use-cases for changing this property to "false" are very rare. Usually you should use UI scaling for 100% of your UI. |
property CapturesEvents: boolean read FCapturesEvents write FCapturesEvents
default true; |
|
Capture input events (keyboard, mouse, joystick). If The only exception is when this control is set as TCastleContainer.ForceCaptureInput. In this case, the control will receive inputs. In other words, TCastleContainer.ForceCaptureInput overrides the intent of this property. This property may be replaced by something like "CaptureInput" or just universal "Enabled" in the future. |
property OnInternalMouseEnter: TUiNotifyEvent
read FOnInternalMouseEnter write FOnInternalMouseEnter; |
|
Called when control starts being under the mouse cursor and will receive events. See SetFocused, this is called when Focused changes from This is called "Internal" now, because we do not guarantee it's 100% always paired with OnInternalMouseLeave. A different approach to this may be done in the future releases. |
property OnInternalMouseLeave: TUiNotifyEvent
read FOnInternalMouseLeave write FOnInternalMouseLeave; |
|
Called when control stops being under the mouse cursor and will receive events. See SetFocused, this is called when Focused changes from This is called "Internal" now, because we do not guarantee it's 100% always paired with OnInternalMouseEnter. A different approach to this may be done in the future releases. |
property Cursor: TMouseCursor read FCursor write SetCursor default mcDefault; |
|
Mouse cursor over this control. When user moves mouse over the Container, the currently focused (topmost under the cursor) control determines the mouse cursor look. |
property OnUpdate: TUiUpdateEvent read FOnUpdate write FOnUpdate; |
|
Event that occurs continuously on each control. See Update for details. |
property OnPress: TUiPressReleaseEvent read FOnPress write FOnPress; |
|
An input (key, mouse button, mouse wheel) was pressed. See Press for details. |
property OnRelease: TUiPressReleaseEvent read FOnRelease write FOnRelease; |
|
An input (key, mouse button, mouse wheel) was released. See Release for details. |
property OnMotion: TUiMotionEvent read FOnMotion write FOnMotion; |
|
Pointer (mouse or finger) moved. See Motion for details. |
property OnRender: TUiNotifyEvent read FOnRender write FOnRender; |
|
Control is being displayed. See Render for details. This event it called after the Render method of this control finished. |
property Exists: boolean read FExists write SetExists default true; |
|
Not existing control is not visible, it doesn't receive input and generally doesn't exist from the point of view of user. This is mostly equivalent to just removing this control from parent list. Non-existing controls still receive GLContextOpen, GLContextClose, Resize events. |
property Left: Single read FLeft write SetLeft stored false default 0; |
|
Position from the left side of the parent control. It's usually better to use anchors instead of this property. For example, instead of setting Note that the effects of this property and HorizontalAnchorDelta are summed, if you set both. |
property Bottom: Single read FBottom write SetBottom default 0; |
|
Position from the bottom side of the parent control. It's usually better to use anchors instead of this property. For example, instead of setting Note that the effects of this property and VerticalAnchorDelta are summed, if you set both. |
property FullSize: boolean read FFullSize write SetFullSize default false; |
|
When See also
|
property Width: Single read FWidth write SetWidth default DefaultWidth; |
|
These properties determine the control size. See the EffectiveRect documentation for details how the size is calculated.
See also
|
property Height: Single read FHeight write SetHeight default DefaultHeight; |
|
property WidthFraction: Single read FWidthFraction write SetWidthFraction default 0.0; |
|
property HeightFraction: Single read FHeightFraction write SetHeightFraction default 0.0; |
|
property AutoSizeToChildren: Boolean
read FAutoSizeToChildren write SetAutoSizeToChildren default false; |
|
Adjust size to encompass all the children. The properties FullSize, Width, Height are ignored in this case. Our Left and Bottom still matter. Our size is adjusted to all existing children sizes and positions. We add AutoSizeToChildrenPaddingTop to the resulting height, and AutoSizeToChildrenPaddingRight to the resulting width. |
property AutoSizeToChildrenPaddingRight: Single
read FAutoSizeToChildrenPaddingRight
write SetAutoSizeToChildrenPaddingRight default 0; |
|
Padding added when AutoSizeToChildren is used. TODO: Should be AutoSizeToChildrenPaddingHorizontal, there's nothing that makes it specific to "right" or "left" side now. |
property AutoSizeToChildrenPaddingTop: Single
read FAutoSizeToChildrenPaddingTop
write SetAutoSizeToChildrenPaddingTop default 0; |
|
Padding added when AutoSizeToChildren is used. TODO: Should be AutoSizeToChildrenPaddingVertical, there's nothing that makes it specific to "top" or "bottom" side now. |
property HorizontalAnchorSelf: THorizontalPosition
read FHorizontalAnchorSelf write SetHorizontalAnchorSelf default hpLeft; |
|
Adjust position to align us to the parent horizontally. The resulting EffectiveRect and RenderRect and RenderRectWithBorder will immediately reflect the new position. Note that HorizontalAnchorDelta is summed with Left. It's usually most natural to leave Left as zero when using anchors. Note that anchors (as well as Left and Bottom) are ignored when FullSize is set to true. In case of FullSize, the control fills the parent perfectly. Anchor distance is automatically affected by TCastleContainer.UIScaling. Which our border to align (it's aligned to parent HorizontalAnchorParent border). |
property HorizontalAnchorParent: THorizontalPosition
read FHorizontalAnchorParent write SetHorizontalAnchorParent default hpLeft; |
|
Which parent border is aligned to our HorizontalAnchorSelf border. |
property HorizontalAnchorDelta: Single
read FHorizontalAnchorDelta write SetHorizontalAnchorDelta default 0; |
|
Delta between our border and parent. |
property VerticalAnchorSelf: TVerticalPosition
read FVerticalAnchorSelf write SetVerticalAnchorSelf default vpBottom; |
|
Adjust position to align us to the parent vertically. The resulting EffectiveRect and RenderRect and RenderRectWithBorder will immediately reflect the new position. Note that VerticalAnchorDelta is summed with Bottom. It's usually most natural to leave Bottom as zero when using anchors. Note that anchors (as well as Left and Bottom) are ignored when FullSize is set to true. In case of FullSize, the control fills the parent perfectly. Anchor distance is automatically affected by TCastleContainer.UIScaling. Which our border to align (it's aligned to parent VerticalAnchorParent border). |
property VerticalAnchorParent: TVerticalPosition
read FVerticalAnchorParent write SetVerticalAnchorParent default vpBottom; |
|
Which parent border is aligned to our VerticalAnchorSelf border. |
property VerticalAnchorDelta: Single
read FVerticalAnchorDelta write SetVerticalAnchorDelta default 0; |
|
Delta between our border and parent. |
property Culling: Boolean read FCulling write SetCulling default false; |
|
Optimize rendering and event processing by checking whether the control can be visible. The visibility is checked by looking at container rectangle, and all possible clipping parents (set by TCastleScrollView, or any other control with ClipChildren). This is useful for UI controls that have expensive rendering or other events (e.g. they do something non-trivial in Render or RenderOverChildren, or they include a lot of children controls). And they may be placed off-screen, or they may be outside of a parent with clipping, which is often the case when the parent is TCastleScrollView. |
property ClipChildren: Boolean read FClipChildren write SetClipChildren default false; |
|
Clip the rendering of children. By default this is When this property is |
property Border: TBorder read FBorder; |
|
Border (by default transparent) of the control. Border adds a space from the control content (drawn within RenderRect) to the control rectangle (returned by RenderRectWithBorder) (scaled), or EffectiveRect (unscaled) and friends). It is transparent by default, but you can change it by BorderColor. Border works always, regardless of FullSize or AutoSizeToChildren. One obvious use-case is to use this for visual space (empty space or a colorful frame, separating this control from the rest). Another use-case is to reserve a predictable space for as additional (sibling) control within the same parent. E.g. you can set FullSize=true and Border.Top=100, and this way there is always a strip with Height=100 at the top of the parent, where you can insert another control (with Height=100, anchored to the top). |
property CustomTheme: TCastleTheme read FCustomTheme write SetCustomTheme; |
|
Use a custom instance of TCastleTheme to determine the look of this control. |
property BorderColorPersistent: TCastleColorPersistent read FBorderColorPersistent ; |
|
BorderColor that can be visually edited in Castle Game Engine Editor, Lazarus and Delphi. Normal user code does not need to deal with this, instead read or write BorderColor directly. See also
|
Generated by PasDoc 0.16.0.