Class TUIControl

DescriptionHierarchyFieldsMethodsProperties

Unit

Declaration

type TUIControl = class(TInputListener)

Description

Basic user interface control class. All controls derive from this class, overriding chosen methods to react to some events. Various user interface containers (things that directly receive messages from something outside, like operating system, windowing library etc.) implement support for such controls.

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.

All screen (mouse etc.) coordinates passed here should be in the usual window system coordinates, that is (0, 0) is left-top window corner. (Note that this is contrary to the usual OpenGL 2D system, where (0, 0) is left-bottom window corner.)

Hierarchy

Overview

Methods

Public constructor Create(AOwner: TComponent); override;
Public destructor Destroy; override;
Public function GetExists: boolean; virtual;
Public function PositionInside(const Position: TVector2Single): boolean; virtual;
Public procedure BeforeRender; virtual;
Public procedure Render; virtual;
Public function RenderStyle: TRenderStyle; virtual;
Public procedure Draw; virtual; deprecated;
Public function DrawStyle: TUIControlDrawStyle; virtual; deprecated;
Public function TooltipStyle: TRenderStyle; virtual;
Public function TooltipExists: boolean; virtual;
Public procedure TooltipRender; virtual;
Public procedure GLContextOpen; virtual;
Public procedure GLContextClose; virtual;
Public procedure SetFocused(const Value: boolean); virtual;

Properties

Public property GLInitialized: boolean read FGLInitialized default false;
Public property DisableContextOpenClose: Cardinal read FDisableContextOpenClose write FDisableContextOpenClose;
Public property Focused: boolean read FFocused write SetFocused;
Published property Exists: boolean read FExists write SetExists default true;

Description

Methods

Public constructor Create(AOwner: TComponent); override;
 
Public destructor Destroy; override;
 
Public function GetExists: boolean; virtual;

Return whether item really exists, see Exists. Non-existing item does not receive any of the render or input or update calls. They only receive GLContextOpen, GLContextClose, ContainerResize calls.

It TUIControl class, this returns the value of Exists property. May be overridden in descendants, to return something more complicated, but it should always be a logical "and" with the inherited GetExists implementation (so setting the Exists := false will always work), like

  Result := (inherited GetExists) and MyComplicatedConditionForExists;

Public function PositionInside(const Position: TVector2Single): boolean; virtual;

Is given position inside this control. Returns always False in this class. Always treated like False when GetExists returns False, so the implementation of this method only needs to make checks assuming that GetExists = True.

Public procedure BeforeRender; virtual;

Prepare your resources, right before drawing. Called only when GetExists and GLInitialized.

Public procedure Render; virtual;

Render a control. Called only when GetExists and GLInitialized, you can depend on it in the implementation of this method.

Do's and don't's when implementing Render:

  • All controls with RenderStyle = rs3D are drawn first.

    The state of projection matrix (GL_PROJECTION for fixed-function pipeline, and global ProjectionMatrix variable) is undefined for rs3D objects. As is the viewport. So you should always set the viewport and projection yourself at the beginning of rs3D rendring, usually by CastleGLUtils.PerspectiveProjection or CastleGLUtils.OrthoProjection. Usually you should just use TCastleSceneManager, which automatically sets projection to something suitable, see TCastleSceneManager.ApplyProjection and TCastleScene.GLProjection.

    Then all the controls with RenderStyle = rs2D are drawn. For them, OpenGL projection is guaranteed to be set to standard 2D that fills the whole screen, like by

      glViewport(0, Container.Width, 0, Container.Height);
      OrthoProjection(0, Container.Width, 0, Container.Height);
    

  • The only OpenGL state you can change carelessly is:

    • The modelview matrix value.

    • rs3D controls can also freely change projection matrix value and viewport.

    • The raster position and WindowPos. The only place in our engine using WindowPos is the deprecated TCastleFont methods (ones without explicit X, Y).

    • The color (glColor), material (glMaterial) values.

    • The line width, point size.

    Every other change should be secured to go back to original value. For older OpenGL, you can use glPushAttrib / glPopAttrib. For things that have guaranteed values at the beginning of draw method (e.g. scissor is always off for rs2D controls), you can also just manually set it back to off at the end (e.g. if you use scissor, them remember to disable it back at the end of draw method.)

  • Things that are guaranteed about OpenGL state when Render is called:

    • The current matrix is modelview, and it's value is identity.

    • Only for RenderStyle = rs2D: the WindowPos is at (0, 0). The projection and viewport is suitable as for 2D, see above.

    • Only for RenderStyle = rs2D: Texturing, depth test, lighting, fog, scissor are turned off.

    If you require anything else, set this yourself.

By default, TUIControl.RenderStyle returns rs2D.

Public function RenderStyle: TRenderStyle; virtual;
 
Public procedure Draw; virtual; deprecated;

Warning: this symbol is deprecated.

Deprecated, you should rather override Render method.

Public function DrawStyle: TUIControlDrawStyle; virtual; deprecated;

Warning: this symbol is deprecated.

Deprecated and ignored, you should rather override RenderStyle method (but usually you don't have to, it's 2D by default).

Public function TooltipStyle: TRenderStyle; virtual;

Render a tooltip of this control. If you want to have tooltip for this control detected, you have to override TooltipExists. Then the TCastleWindowCustom.TooltipVisible will be detected, and your TooltipRender will be called.

The values of rs2D and rs3D are interpreted in the same way as RenderStyle. And TooltipRender is called in the same way as Render, so e.g. you can safely assume that modelview matrix is identity and (for 2D) WindowPos is zero. TooltipRender is always called as a last (front-most) 2D or 3D control.

Public function TooltipExists: boolean; virtual;
 
Public procedure TooltipRender; virtual;
 
Public procedure GLContextOpen; virtual;

Initialize your OpenGL resources.

This is called when OpenGL context of the container is created. Also called when the control is added to the already existing context. In other words, this is the moment when you can initialize OpenGL resources, like display lists, VBOs, OpenGL texture names, etc.

As an exception, this is called regardless of the GetExists value. This way a control can prepare it's resources, regardless if it exists now.

Public 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 Controls list. Also called from the destructor.

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 GetExists value. This way a control can release it's resources, regardless if it exists now.

Public procedure SetFocused(const Value: boolean); virtual;

Called when this control becomes or stops being focused. In this class, they simply update Focused property.

Properties

Public property GLInitialized: boolean read FGLInitialized default false;
 
Public property DisableContextOpenClose: Cardinal read FDisableContextOpenClose write FDisableContextOpenClose;

When non-zero, control will not receive GLContextOpen and GLContextClose events when it is added/removed from the TUIContainer.Controls list.

This can be useful as an optimization, to keep the OpenGL resources created even for controls that are not present on the TUIContainer.Controls list. This must used very, very carefully, as bad things will happen if the actual OpenGL context will be destroyed while the control keeps the OpenGL resources (because it had DisableContextOpenClose > 0). The control will then remain having incorrect OpenGL resource handles, and will try to use them, causing OpenGL errors or at least weird display artifacts.

Most of the time, when you think of using this, you should instead use the TUIControl.Exists property. This allows you to keep the control of the TUIContainer.Controls list, and it will be receive GLContextOpen and GLContextClose events as usual, but will not exist for all other purposes.

Using this mechanism is only sensible if you want to reliably hide a control, but also allow readding it to the TUIContainer.Controls list, and then you want to show it again. This is useful for CastleWindowModes, that must push (and then pop) the controls, but then allows the caller to modify the controls list. And some games, e.g. castle1, add back some (but not all) of the just-hidden controls. For example the TCastleNotifications instance is added back, to be visible even in the menu mode. This means that CastleWindowModes cannot just modify the TUIContainer.Exists value, leaving the control on the TUIContainer.Controls list: it would leave the TUIControl existing many times on the TUIContainer.Controls list, with the undefined TUIContainer.Exists value.

Public property Focused: boolean read FFocused write SetFocused;
 
Published 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. You can also remove this from controls list (like TCastleWindowCustom.Controls), but often it's more comfortable to set this property to false.


Generated by PasDoc 0.13.0 on 2014-04-30 22:06:45