Class TCastleContainer

Unit

Declaration

type TCastleContainer = class abstract(TComponent)

Description

Abstract user interface container. Connects OpenGL context management code with Castle Game Engine controls (TCastleUserInterface, that is the basis for all our 2D and 3D rendering). When you use TCastleWindow (a window) or TCastleControl (Lazarus component), they provide you a non-abstract implementation of TCastleContainer.

Basically, this class manages a Controls list.

We pass our inputs (mouse / key / touch events) to the controls on this list. Input goes to the front-most (that is, last on the Controls list) control under the event position (or mouse position, or the appropriate touch position). We use TCastleUserInterface.CapturesEventsAtPosition to decide this (by default it simply checks control's TCastleUserInterface.RenderRect vs the given position). As long as the event is not handled, we search for the next control that can handle this event and returns TCastleUserInterface.CapturesEventsAtPosition = True.

We also call various methods to every control. These include TCastleUserInterface.Update, TCastleUserInterface.Render, TCastleUserInterface.Resize.

Hierarchy

  • TObject
  • TPersistent
  • TComponent
  • TCastleContainer

Overview

Fields

Public var UserInterfaceBatching: Boolean;
Public nested const DefaultBackgroundColor: TVector4 = (X: 0.1; Y: 0.1; Z: 0.1; W: 1);

Methods

Protected procedure Notification(AComponent: TComponent; Operation: TOperation); override;
Protected procedure SetInternalCursor(const Value: TMouseCursor); virtual;
Protected procedure SystemSetMousePosition(const Value: TVector2); virtual;
Protected procedure InitializeMousePosition(const Value: TVector2);
Protected function SettingMousePositionCausesMotion: Boolean; virtual;
Public constructor Create(AOwner: TComponent); override;
Public destructor Destroy; override;
Public procedure EventOpen(const InitializedContextsCount: Cardinal);
Public procedure EventClose(const InitializedContextsCount: Cardinal);
Public function EventPress(const Event: TInputPressRelease): Boolean;
Public function EventRelease(const Event: TInputPressRelease): Boolean;
Public procedure EventUpdate;
Public procedure EventMotion(const Event: TInputMotion);
Public procedure EventBeforeRender;
Public procedure EventRender;
Public procedure EventResize;
Public function EventJoyAxisMove(const JoyID, Axis: Byte): Boolean;
Public function EventJoyButtonPress(const JoyID, Button: Byte): Boolean;
Public function EventSensorRotation(const X, Y, Z, Angle: Double; const SecondsPassed: Single): Boolean;
Public function EventSensorTranslation(const X, Y, Z, Length: Double; const SecondsPassed: Single): Boolean;
Public function AllowSuspendForInput: Boolean;
Public function Controls: TInternalChildrenControls;
Public function FocusFront: TCastleUserInterface;
Public procedure Invalidate; virtual;
Public function GLInitialized: Boolean; virtual;
Public function PixelsWidth: Integer; virtual; abstract;
Public function PixelsHeight: Integer; virtual; abstract;
Public function PixelsRect: TRectangle; virtual;
Public function Width: Integer; deprecated 'use PixelsWidth or UnscaledWidth, depending on what you need; for backward compatibility, "Width" is equal to "PixelsWidth" now, but it will change to "UnscaledWidth" in the future';
Public function Height: Integer; deprecated 'use PixelsHeight or UnscaledHeight, depending on what you need; for backward compatibility, "Height" is equal to "PixelsHeight" now, but it will change to "UnscaledHeight" in the future';
Public function Rect: TRectangle; deprecated 'use PixelsRect or UnscaledRect, depending on what you need; for backward compatibility, "Rect" is equal to "PixelsRect" now, but it will change to "UnscaledRect" in the future';
Public function ScaledStatusBarHeight: Cardinal; deprecated 'use SafeBorder';
Public function UnscaledWidth: Single;
Public function UnscaledHeight: Single;
Public function UnscaledRect: TFloatRectangle;
Public function StatusBarHeight: Single; deprecated 'use SafeBorder';
Public function Focused: Boolean; virtual;
Public function TouchesCount: Integer;
Public procedure RenderControl(const Control: TCastleUserInterface; const ViewportRect: TRectangle);
Public procedure SaveScreen(const Url: String); overload;
Public function SaveScreen: TRGBImage; overload;
Public function SaveScreen(const SaveRect: TRectangle): TRGBImage; overload; virtual;
Public function SaveScreen(const SaveRect: TFloatRectangle): TRGBImage; overload;
Public function SaveScreenRgba(const SaveRect: TRectangle): TRGBAlphaImage; overload;
Public function SaveScreenRgba: TRGBAlphaImage; overload;
Public function SaveScreenToDefaultFile: String;
Public procedure MouseLookPress;
Public procedure MouseLookUpdate;
Public function MouseLookDelta(const Event: TInputMotion; const ControlRect: TFloatRectangle): TVector2; overload;
Public function MouseLookDelta(const Event: TInputMotion): TVector2; overload; deprecated 'use MouseLookDelta overload with ControlRect parameter';
Public procedure ReleaseCapture(const C: TCastleUserInterface);
Public procedure LoadSettings(const SettingsUrl: String);
Public procedure InternalTooltipHide;
Public procedure PushView(const NewView: TCastleView);
Public procedure PopView; overload;
Public procedure PopView(const CheckFrontView: TCastleView); overload;
Public function ViewStackCount: Integer;
Public function SafeBorder: TBorder;

Properties

Protected property Cursor: TMouseCursor write SetInternalCursor; deprecated 'do not set this, engine will override this. Set TCastleUserInterface.Cursor of your UI controls to control the Cursor.';
Protected property InternalCursor: TMouseCursor write SetInternalCursor;
Public property Dpi: Single read FDpi write SetDpi default DefaultDpi;
Public property UIScale: Single read FUIScale;
Public property Focus: TCastleUserInterfaceList read FFocus;
Public property MousePosition: TVector2 read GetMousePosition write SetMousePosition;
Public property MousePressed: TCastleMouseButtons read FMousePressed ;
Public property Pressed: TKeysPressed read FPressed;
Public property Fps: TFramesPerSecond read FFps;
Public property Touches[const Index: Integer]: TTouch read GetTouches;
Public property Context: TRenderContext read FContext;
Public property ForceCaptureInput: TCastleUserInterface read FForceCaptureInput write SetForceCaptureInput;
Public property OverrideCursor: TMouseCursor read FOverrideCursor write FOverrideCursor default mcDefault;
Public property TooltipDelay: Single read FTooltipDelay write FTooltipDelay default DefaultTooltipDelay;
Public property TooltipDistance: Cardinal read FTooltipDistance write FTooltipDistance default DefaultTooltipDistance;
Public property UIScaling: TUIScaling read FUIScaling write SetUIScaling default usNone;
Public property UIReferenceWidth: Single read FUIReferenceWidth write SetUIReferenceWidth default 0;
Public property UIReferenceHeight: Single read FUIReferenceHeight write SetUIReferenceHeight default 0;
Public property UIExplicitScale: Single read FUIExplicitScale write SetUIExplicitScale default 1.0;
Public property DefaultFont: TCastleAbstractFont read FDefaultFont write FDefaultFont;
Public property BackgroundEnable: Boolean read FBackgroundEnable write FBackgroundEnable default true;
Public property BackgroundColor: TCastleColor read FBackgroundColor write FBackgroundColor;
Public class property InputInspector: TInputInspector read FInputInspector;
Public property InspectorKey: TKey read GetInspectorKey write SetInspectorKey; deprecated 'use InputInspector';
Public property View: TCastleView read GetView write SetView;
Public property FrontView: TCastleView read GetFrontView;
Public property ViewStack [const Index: Integer]: TCastleView read GetViewStack;
Public property OnSafeBorderChanged: TNotifyEvent read FOnSafeBorderChanged write FOnSafeBorderChanged;

Description

Fields

Public var UserInterfaceBatching: Boolean;

Optimize rendering of user interface. This activates batching of TDrawableImage around whole rendering, and TDrawableImage is used for most UI rendering (labels, images).

Where it works, where it doesn't: The automatic batching offered by TDrawableImage.BatchingBegin and TDrawableImage.BatchingEnd gives a benefit when the same TDrawableImage is rendered multiple times in a row, with the same parameters. Consider these examples:

  • The batching helps if you have multiple TCastleImageControl (rendered one after another) with the same image.

    Note that by default TCastleImageControl (actually TCastleImagePersistent underneath) does caching so same image URL -> same TDrawableImage instance. This is good for batching.

  • The batching helps if you have multiple TCastleLabel instances rendered one after another, and/or they have multiline text, all using the same font.

  • The batching will not help for typical TCastleButton, as a button is typically some image (background) + some text, so the TDrawableImage drawn switches between background / text, and nothing gets batched.

Observe TDrawableImage.Statistics.ToString to actually measure how much you gain by this. See example examples/user_interface/ui_batching/.

Public nested const DefaultBackgroundColor: TVector4 = (X: 0.1; Y: 0.1; Z: 0.1; W: 1);

This item has no description.

Methods

Protected procedure Notification(AComponent: TComponent; Operation: TOperation); override;

This item has no description.

Protected procedure SetInternalCursor(const Value: TMouseCursor); virtual;

This item has no description.

Protected procedure SystemSetMousePosition(const Value: TVector2); virtual;

Descendants should override this to change the mouse position on explicit request (from engine or application code, e.g. mouse look repositions the mouse to the center of the screen). This is not called when mouse position changes because of user input, which is handled inside EventMotion. This is not called when the window / contained is closed.

Protected procedure InitializeMousePosition(const Value: TVector2);

Call this when the initial mouse position is known, right when we open the window or make it focused again. This doesn't ever cause SystemSetMousePosition, it should be used only to tell the engine what the *current* mouse position really is.

Protected function SettingMousePositionCausesMotion: Boolean; virtual;

Does setting MousePosition also causes Motion / OnMotion events. While we tried to make everything work reliably always, the mouse look logic just needs to know this.

It is easy to test it in practice. Just run examples/window/window_events.lpr, move mouse around, and press "5" (this does "MousePosition := window middle").

Public constructor Create(AOwner: TComponent); override;

This item has no description.

Public destructor Destroy; override;

This item has no description.

Public procedure EventOpen(const InitializedContextsCount: Cardinal);

Rendering context (like OpenGL) was just created.

In case of using TCastleWindow, this is always called after Application.OnInitialize.

In normal circumstances, for a typical standalone game, this will happen only once. But for other targets, it may be necessary to close/reopen the rendering context many times, e.g. on mobile platforms it's normal that application may loose the OpenGLES context and it may need to recreate OpenGLES resources when it wakes up.

So be careful what you do in this callback if you want your game to work on Android or other non-standalone platforms. On mobile, OpenGL context may be closed and opened at any time, as user can switch from/to your application at any time. You should use Application.OnInitialize for a one-time initialization (it is executed right before the very first OnOpen would be executed). Use this callback only to create OpenGL resources (destroyed in OnClose).

It's guaranteed that every newly opened container will get EventOpen first, and then EventResize, and only then — the other callbacks, as the user uses the window. In effect EventOpen is always the first executed callback and EventClose is always the last. This allows you to cleanly initialize / finalize rendering resources.

During EventOpen you already have valid PixelsWidth / PixelsHeight values, that is those values were already adjusted if ResizeAllowed <> raNotAllowed.

Parameters
InitializedContextsCount
The number of initialized contexts at this point. This is always >= 1 since the current context is always initialized at the point of this call. So for EventOpen, InitializedContextsCount = 1 means we initialize 1st context, and for EventClose, InitializedContextsCount = 1 means we finalize last context.
Public procedure EventClose(const InitializedContextsCount: Cardinal);

Rendering context (like OpenGL) will be destroyed.

Parameters
InitializedContextsCount
See EventOpen
Public function EventPress(const Event: TInputPressRelease): Boolean;

User presses a key, mouse button or moves the mouse wheel.

This calls TCastleUserInterface.Press methods for all controls that should receive information about this event. This means controls under the mouse (from Event.Position), ForceCaptureInput control (if any).

This also updates MousePressed, MousePosition, Touches when this is a press of a mouse button. They are updated before calling the TCastleUserInterface.Press.

Public function EventRelease(const Event: TInputPressRelease): Boolean;

User releases a pressed key or mouse button.

This calls TCastleUserInterface.Release methods for all controls that should receive information about this event. This means controls under the mouse (from Event.Position), ForceCaptureInput control (if any), control capturing the input (when you press a mouse/finger over a control we make sure that subsequent motion/release reach this control, regardless if the position is over the same control; X Windows has similar mechanism).

This also updates MousePressed, MousePosition, Touches when this is a release of a mouse button. They are updated before calling the TCastleUserInterface.Release.

It's called right after Pressed[Key] changed from true to false.

The TInputPressRelease structure, passed as a parameter to this event, contains the exact information what was released.

Note that reporting characters for "key release" messages is not perfect, as various key combinations (sometimes more than one?) may lead to generating given character. We have some intelligent algorithm for this, used to make Characters table and to detect this C for OnRelease callback. The idea is that a character is released when the key that initially caused the press of this character is also released.

This solves in a determined way problems like "what happens if I press Shift, then X, then release Shift, then release X". (will "X" be correctly released as pressed and then released? yes. will small "x" be reported as released at the end? no, as it was never pressed.)

Public procedure EventUpdate;

Continuously occuring event. This event is called roughly as regularly as redraw, and you should use this to update your game state.

This is called at the same time (right after or right before) when all callbacks on the list ApplicationProperties.OnUpdate are called.

Note that this is different than LCL "idle" event, as it's guaranteed to be run continuously, even when your application is overwhelmed by messages (like mouse moves) and redraws.

Public procedure EventMotion(const Event: TInputMotion);

Mouse or a finger on touch device moved.

For a mouse, remember you always have the currently pressed mouse buttons in MousePressed. When this is called, the MousePosition property records the previous mouse position, while callback parameter NewMousePosition gives the new mouse position.

Public procedure EventBeforeRender;

Called right before EventRender. These two events, EventBeforeRender and EventRender, are always called sequentially as a pair.

Time spent in EventBeforeRender is not counted as "frame time" by Fps.OnlyRenderFps, in contrast to the time spent in EventRender. This is useful when you have something that needs to be done from time to time right before EventRender and that is very time-consuming. It such cases it is not desirable to put such time-consuming task inside EventRender because this would cause a sudden big change in Fps.OnlyRenderFps value. So you can put it in EventBeforeRender.

Public procedure EventRender;

Render the container contents.

Called when the window needs to be redrawn, this includes various cases: when it has to be redrawn because window was resized, when it has to be drawn for the 1st time (after creation), when it's no longer obscured by other window, and finally when we redraw all the time because of AutoRedisplay.

Note that calling Invalidate while in EventRender is not ignored. It instructs to call EventRender again, as soon as possible.

Public procedure EventResize;

Container size changed. It's also guaranteed to be called right after the EventOpen event.

Public function EventJoyAxisMove(const JoyID, Axis: Byte): Boolean;

Joystick or 3D mouse event happened. These events are special now: they are called by EventUpdate, we don't expect that TCastleWindow or TCastleControl will call them.

Public function EventJoyButtonPress(const JoyID, Button: Byte): Boolean;

This item has no description.

Public function EventSensorRotation(const X, Y, Z, Angle: Double; const SecondsPassed: Single): Boolean;

This item has no description.

Public function EventSensorTranslation(const X, Y, Z, Length: Double; const SecondsPassed: Single): Boolean;

This item has no description.

Public function AllowSuspendForInput: Boolean;

This item has no description.

Public function Controls: TInternalChildrenControls;

Controls listening for events (user input, resize, and such) of this container.

Usually you explicitly add / remove controls to this list using the Controls.InsertFront or Controls.InsertBack methods. Freeing any control that is on this list automatically removes it from this list (we use the TComponent.Notification mechanism).

Controls on the list should be specified in back-to-front order. That is, controls at the beginning of this list are rendered first, and are last to catch some events, since the rest of controls cover them.

Public function FocusFront: TCastleUserInterface;

First control that receives input events, determined by Focus list and ForceCaptureInput. Nil if none.

Be careful when using this: most logic should account for the fact that multiple controls may be focused, that's why Focus is a list. Use this only when you need to know the front-most focused control.

Public procedure Invalidate; virtual;

Redraw the contents of of this window, at the nearest suitable time. This method does not redraw immediately (it does not call EventBeforeRender and EventRender inside), it only makes sure that they will be called very soon. Calling this on a closed container (with GLInitialized = False) is allowed and ignored.

Public function GLInitialized: Boolean; virtual;

Is the OpenGL context initialized.

Public function PixelsWidth: Integer; virtual; abstract;

Container size, in pixels. This is expressed in real device pixels. Prefer using UnscaledWidth instead of this. UnscaledWidth is more natural when you use UI scaling (UIScaling), and it's simply equal to PixelsWidth when UI scaling is not used.

Public function PixelsHeight: Integer; virtual; abstract;

Container size, in pixels. This is expressed in real device pixels. Prefer using UnscaledHeight instead of this. UnscaledHeight is more natural when you use UI scaling (UIScaling), and it's simply equal to PixelsHeight when UI scaling is not used.

Public function PixelsRect: TRectangle; virtual;

Container size, in pixels. This is expressed in real device pixels, using Width and Height. Prefer using UnscaledRect instead of this. UnscaledRect is more natural when you use UI scaling (UIScaling), and it's simply equal to PixelsRect when UI scaling is not used.

Public function Width: Integer; deprecated 'use PixelsWidth or UnscaledWidth, depending on what you need; for backward compatibility, "Width" is equal to "PixelsWidth" now, but it will change to "UnscaledWidth" in the future';

Warning: this symbol is deprecated: use PixelsWidth or UnscaledWidth, depending on what you need; for backward compatibility, "Width" is equal to "PixelsWidth" now, but it will change to "UnscaledWidth" in the future

This item has no description.

Public function Height: Integer; deprecated 'use PixelsHeight or UnscaledHeight, depending on what you need; for backward compatibility, "Height" is equal to "PixelsHeight" now, but it will change to "UnscaledHeight" in the future';

Warning: this symbol is deprecated: use PixelsHeight or UnscaledHeight, depending on what you need; for backward compatibility, "Height" is equal to "PixelsHeight" now, but it will change to "UnscaledHeight" in the future

This item has no description.

Public function Rect: TRectangle; deprecated 'use PixelsRect or UnscaledRect, depending on what you need; for backward compatibility, "Rect" is equal to "PixelsRect" now, but it will change to "UnscaledRect" in the future';

Warning: this symbol is deprecated: use PixelsRect or UnscaledRect, depending on what you need; for backward compatibility, "Rect" is equal to "PixelsRect" now, but it will change to "UnscaledRect" in the future

This item has no description.

Public function ScaledStatusBarHeight: Cardinal; deprecated 'use SafeBorder';

Warning: this symbol is deprecated: use SafeBorder

Translucent status bar height in the container, in pixels. This is expressed in real device pixels.

Prefer using SafeBorder instead of this, SafeBorder accounts for all 4 sides and is in size accounting for UI scaling.

Public function UnscaledWidth: Single;

Container width as seen by controls with UI scaling. In other words, this is the real Width with UI scaling reversed (divided). Suitable to adjust size of your UI controls to container, when UI scaling is used.

This is equivalent to just Width when UIScaling is usNone (default).

Note: the name "unscaled" may seem a little unintuitive, but it's consistent. We call UI sizes "scaled" when they are expressed in real device pixels, because they are usually calculated as "desired size * UIScaling". So the UI size is "unscaled" when it's expressed in your "desired size". We usually don't use the prefix "unscaled" (e.g. TCastleUserInterface.Width is "unscaled" by we don't call it "UnscaledWidth"). But here, we use prefix "unscaled", because the TCastleContainer.Width is (for historic reasons) the "real" size.

See also
UnscaledHeight
Container height as seen by controls with UI scaling.
Public function UnscaledHeight: Single;

Container height as seen by controls with UI scaling.

See also
UnscaledWidth
Container width as seen by controls with UI scaling.
Public function UnscaledRect: TFloatRectangle;

Container rectangle as seen by controls with UI scaling.

See also
UnscaledWidth
Container width as seen by controls with UI scaling.
Public function StatusBarHeight: Single; deprecated 'use SafeBorder';

Warning: this symbol is deprecated: use SafeBorder

Translucent status bar height inside the container as seen by controls with UI scaling.

Status bar occupies the top part of the container height. Invisible status bar returns height equal zero.

Prefer using SafeBorder instead of this, SafeBorder accounts for all 4 sides and (just like this) is also in size accounting for UI scaling.

See also
UnscaledWidth
Container width as seen by controls with UI scaling.
Public function Focused: Boolean; virtual;

Is the window focused now, which means that keys/mouse events are directed to this window.

Public function TouchesCount: Integer;

Count of currently active touches (mouse or fingers pressed) on the screen.

See also
Touches
Currently active touches on the screen.
Public procedure RenderControl(const Control: TCastleUserInterface; const ViewportRect: TRectangle);

Render a TCastleUserInterface (along with all it's children).

This method can be used to render UI control into an image, TDrawableImage, when it is surrounded by TDrawableImage.RenderToImageBegin and TDrawableImage.RenderToImageEnd. See CGE examples/viewport_and_scenes/render_3d_to_image/ .

It can also be used with more low-level TGLRenderToTexture. See CGE examples/viewport_and_scenes/render_3d_to_texture_and_use_as_quad/ .

This is a good method to render the UI control off-screen. It can render any UI control, including e.g. TCastleViewport with 3D stuff inside TCastleScene.

The contents of the Controls list doesn't matter for this method. In particular, it doesn't matter if the Control (given as a parameter) is present on the list of current Controls. This method explicitly renders the given Control parameter (and it's children), nothing more, nothing less.

More details what this method does:

Public procedure SaveScreen(const Url: String); overload;

Capture the current container (window) contents to an image (or straight to an image file, like png).

Note that only capturing from the double-buffered OpenGL windows (which the default for our TCastleWindow and TCastleControl) is reliable. Internally, these methods may need to redraw the screen to the back buffer, because that's the only guaranteed way to capture OpenGL drawing (you have to capture the back buffer, before swap).

Public function SaveScreen: TRGBImage; overload;

This item has no description.

Public function SaveScreen(const SaveRect: TRectangle): TRGBImage; overload; virtual;

This item has no description.

Public function SaveScreen(const SaveRect: TFloatRectangle): TRGBImage; overload;

This item has no description.

Public function SaveScreenRgba(const SaveRect: TRectangle): TRGBAlphaImage; overload;

Capture the current container (window) contents to an image with alpha.

An example:

{ TCastleContainer.SaveScreenRgba example.

  This example relies on OpenGL color buffer that can store alpha information,
  which you request by "Window.AlphaBits := 8".

  An alternative approach, without needing "Window.AlphaBits := xxx",
  is to initialize FBO with color framebuffer with alpha channel,
  and render using this Fbo, like this:

    Fbo := TGLRenderToTexture.Create(Window.Width, Window.Height);
    Fbo.Buffer := tbNone;
    Fbo.ColorBufferAlpha := true;
    Fbo.GLContextOpen;
    Fbo.RenderBegin;
    ...
    Fbo.RenderEnd;
}
uses SysUtils,
  CastleWindow, CastleLog, CastleVectors, CastleUIControls, CastleScene,
  CastleViewport, CastleKeysMouse, CastleImages, CastleCameras;

{ View ----------------------------------------------------------------------- }

type
  { View to contain whole UI and to handle events, like key press. }
  TMyView = class(TCastleView)
    function Press(const Event: TInputPressRelease): Boolean; override;
  end;

var
  MyView: TMyView;

function TMyView.Press(const Event: TInputPressRelease): Boolean;
var
  Image: TRGBAlphaImage;
begin
  Result := inherited;
  if Result then Exit;

  if Event.IsKey(keyF5) then
  begin
    Image := Container.SaveScreenRgba;
    try
      SaveImage(Image, 'save_screen_rgba.png');
    finally FreeAndNil(Image) end;
    Exit(true);
  end;
end;

var
  Window: TCastleWindow;
  Viewport: TCastleViewport;
  Scene: TCastleScene;
begin
  Window := TCastleWindow.Create(Application);
  // We must have buffer that stores alpha information, not only RGB
  Window.AlphaBits := 8;
  // Initially fill buffer with transparent white.
  // When displaying, the window will be white, but it will be saved as transparent white.
  Window.Container.BackgroundColor := Vector4(1, 1, 1, 0);
  Window.Open;

  MyView := TMyView.Create(Application);
  Window.Container.View := MyView;

  Viewport := TCastleViewport.Create(Application);
  Viewport.FullSize := true;
  Viewport.InsertBack(TCastleExamineNavigation.Create(Application));
  Viewport.Transparent := true; // do not fill parent with Viewport.BackgroundColor
  MyView.InsertFront(Viewport);

  Scene := TCastleScene.Create(Application);
  Scene.Load('castle-data:/teapot.x3dv');
  Scene.PreciseCollisions := true;
  Scene.ProcessEvents := true;
  Viewport.Items.Add(Scene);

  // headlight
  Viewport.Camera.Add(TCastleDirectionalLight.Create(Application));

  // nice initial camera position
  Viewport.AssignDefaultCamera;

  Application.Run;
end.

Public function SaveScreenRgba: TRGBAlphaImage; overload;

This item has no description.

Public function SaveScreenToDefaultFile: String;

Capture the current container (window) contents to an image and save it to file, following the current platform/user preferred directory to store screenshots.

On Windows, this saves files to user's "My Pictures" directory. On Unix (using freedesktop standard) this saves files to directory like ~/Pictures . On macOS, this saves files to the home directory right now. On other platforms, it may follow the most established convention, or abort if no place (where we have permissions to store screenshots) exists.

You can use SaveScreenPath yourself to have more control over the target location.

Returns the saved file URL, so that you can e.g. show it to user.

Public procedure MouseLookPress;

For tracking mouse look. See MouseLookDelta.

Public procedure MouseLookUpdate;

For tracking mouse look. See MouseLookDelta.

Public function MouseLookDelta(const Event: TInputMotion; const ControlRect: TFloatRectangle): TVector2; overload;

Read mouse position delta from ControlRect middle, and try to set mouse position to ControlRect middle.

ControlRect is usually the container rectangle (in final device coordinates) but in general it should be the rectangle of control over which we should do mouse look (so TCastleUserInterface.RenderRect).

This can be used to perform "mouse look" or a similar effect, when user doesn't see the mouse cursor, but user can move something by dragging with mouse. Moreover, user should not notice any "bounds" to this dragging (that's why we try to keep mouse position in ControlRect middle, to avoid screen borders from acting as constrains on mouse movement).

This is automatically used by TCastleWalkNavigation.MouseLook. You can use it yourself for custom effects "like mouse look". The template to use this is below. See the CGE example examples/user_interface/dragging_test/ for a working code demonstrating this.


function TMyState.Press(const Event: TInputPressRelease): Boolean;
begin
  Result := inherited;
  if Result then Exit;

  if Event.IsMouseButton(buttonLeft) then
  begin
    Drag := true;
    Cursor := mcForceNone;
    Container.MouseLookPress;
  end;
end;

function TMyState.Release(const Event: TInputPressRelease): Boolean;
begin
  Result := inherited;
  if Result then Exit;

  if Event.IsMouseButton(buttonLeft) then
  begin
    Drag := false;
    Cursor := mcDefault;
  end;
end;

procedure TMyState.Update(const SecondsPassed: Single;
  var HandleInput: Boolean);
begin
  inherited;
  if Drag then
    Container.MouseLookUpdate;
end;

function TNewFightUi.Motion(const Event: TInputMotion): Boolean;
var
  Delta: TVector2;
begin
  Result := inherited;
  if Result then Exit;

  if Drag then
  begin
    Delta := Container.MouseLookDelta(Event, Container.Rect);
    // ...
    // Use Delta to perform any logic you want.
    // It may be zero if mouse was not positioned correctly yet,
    // just make sure that Delta=zero does nothing.
    // You can use Delta / UiScale to adjust to UI scale
    // (user will then have to move mouse by more pixels on a larger screen to achieve the same Delta).
    // ...
  end;
end;

Public function MouseLookDelta(const Event: TInputMotion): TVector2; overload; deprecated 'use MouseLookDelta overload with ControlRect parameter';

Warning: this symbol is deprecated: use MouseLookDelta overload with ControlRect parameter

This item has no description.

Public procedure ReleaseCapture(const C: TCastleUserInterface);

When the control accepts the "press" event, it automatically captures the following motion and release events, hijacking them from other controls, regardless of the mouse cursor position. This is usually desirable, to allow the control to handle the dragging. But sometimes you want to cancel the dragging, and allow other controls to handle the following motion and release events, in which case calling this method helps.

Public procedure LoadSettings(const SettingsUrl: String);

Load application settings from an XML file. See https://castle-engine.io/manual_castle_settings.php for a documentation of the file format.

This loads UIScaling, UIReferenceWidth, UIReferenceHeight, DefaultFont. It allows "warms the cache" by loading some assets into it – which means that actually instatiating them at runtime will be faster.

Note: It is allowed to call this at any moment, even before the rendering context is initialized. That's because it makes sense in some cases: e.g. if using with LCL / FMX form, it is natural to call this in TForm.OnCreate callback, without the additional complexity of waiting for context (e.g. by waiting for GLContextOpen call on some TCastleUserInterface instance).

We still recommend to call this only once rendering context is available, in case you use "warmup cache" feature ( https://castle-engine.io/manual_castle_settings.php#section_warmup_cache ). The cache will be initialized better (with rendering resoruces too) if you call this after rendering context is available. It is easiest if you use TCastleWindow: just do this in Application.OnInitialize callback, which is called after rendering context is available and is natural place to initialize stuff.

Public procedure InternalTooltipHide;

Hide the tooltip, if was displayed, right now. Useful if you e.g. want to make a screenshot now - e.g. for castle-model-viewer-mobile. TODO: Would be more natural to hide tooltip when parent exists:=false, and then this is unnecessary.

Public procedure PushView(const NewView: TCastleView);

Pushing the view adds it at the top of the view stack, this makes new view to be displayed on top of previous ones.

The view known as View is conceptually at the bottom of view stack, always. When it is nil, then pushing new view sets the View view. Otherwise View view is left as-it-is, new view is added on top.

Public procedure PopView; overload;

Pop the current top-most view, reversing the PushView operation.

Public procedure PopView(const CheckFrontView: TCastleView); overload;

Pop the current top-most view, reversing the PushView operation, also checking whether the current top-most view is as expected.

Makes a warning, and does nothing, if the current top-most view is different than indicated. This is usually a safer (more chance to easily catch bugs) version of PopView than the parameter-less version.

Public function ViewStackCount: Integer;

Count of views in the view stack. View stack is managed using View / PushView / PopView.

Public function SafeBorder: TBorder;

Safe border sizes you should honor in your UI design (do not place there UI elements that have to be readable or clickable, like labels or buttons) on mobile devices.

This is important for full-screen Android and iOS applications. You have to leave this space empty, that is: place there simple unimportant UI – solid color, gradients. And be prepared it may be partially or completely obscured by the device's status bar (on top, with stuff like clock, battery, network status) or physical things obscuring the screen.

This is also sometimes called "safe area", "display cutout", "statusBarHeight" (top), "bottomBarHeight" (bottom). See e.g. Android docs: https://developer.android.com/design/ui/mobile/guides/foundations/system-bars .

Properties

Protected property Cursor: TMouseCursor write SetInternalCursor; deprecated 'do not set this, engine will override this. Set TCastleUserInterface.Cursor of your UI controls to control the Cursor.';

Warning: this symbol is deprecated: do not set this, engine will override this. Set TCastleUserInterface.Cursor of your UI controls to control the Cursor.

This item has no description.

Protected property InternalCursor: TMouseCursor write SetInternalCursor;

This item has no description.

Public property Dpi: Single read FDpi write SetDpi default DefaultDpi;

Dots (pixels) per inch. Describes how many pixels fit on a physical inch. So this is determined by the screen resolution in pixels, and by the physical size of the device.

Some systems may expose a value that actually reflects user preference "how to scale the user-interface", where 96 (DefaultDpi) is default. So do not depend that it is actually related to the physical monitor size. See https://developer.gnome.org/gdk2/stable/GdkScreen.html#gdk-screen-set-resolution .

Public property UIScale: Single read FUIScale;

Get the default UI scale of controls. Useful only when GLInitialized, when we know that our size is sensible.

UI code should prefer to use TCastleUserInterface.UIScale, not directly accessing this TCastleContainer.UIScale (this way the code respects the TCastleUserInterface.EnableUIScaling value).

Public property Focus: TCastleUserInterfaceList read FFocus;

Returns the controls that should receive input events, from back to front. So the front-most control, that should receive events first, is last on this list.

Public property MousePosition: TVector2 read GetMousePosition write SetMousePosition;

Current mouse position. See TTouch.Position for a documentation how this is expressed.

Public property MousePressed: TCastleMouseButtons read FMousePressed ;

Currently pressed mouse buttons. When this changes, you're always notified by TCastleUserInterface.OnPress or TCastleUserInterface.OnRelease events.

This value is always current, in particular it's already updated before we call events TCastleUserInterface.OnPress or TCastleUserInterface.OnRelease.

Public property Pressed: TKeysPressed read FPressed;

Keys currently pressed.

Public property Fps: TFramesPerSecond read FFps;

Measures application speed.

Public property Touches[const Index: Integer]: TTouch read GetTouches;

Currently active touches on the screen. This tracks currently pressed fingers, in case of touch devices (mobile, like Android and iOS). In case of desktops, it tracks the current mouse position, regardless if any mouse button is currently pressed.

Indexed from 0 to TouchesCount - 1.

See also
TouchesCount
Count of currently active touches (mouse or fingers pressed) on the screen.
TTouch
Tracking of a touch by a single finger, used by TTouchList.
Public property Context: TRenderContext read FContext;

This item has no description.

Public property ForceCaptureInput: TCastleUserInterface read FForceCaptureInput write SetForceCaptureInput;

Force passing events to the given control first, regardless if this control is under the mouse cursor. Before we even send events to the currently "capturing" control (for example, when you're dragging the slider, it is "capturing" mouse events until you release the mouse), they are send to this control.

The control given here will always have focus (that is, TCastleUserInterface.Focused will be set to true shortly after it becomes the ForceCaptureInput).

An example when this is useful is when you use camera MouseLook, and the associated viewport does not fill the full window (TCastleViewport.FullSize is False, and actual sizes are smaller than window, and may not include window center). In this case you want to make sure that motion events get passed to this control, and that this control has focus (to keep mouse cursor hidden).

The engine itself never automatically sets this property. It is up to your application code to set this, if you need.

Public property OverrideCursor: TMouseCursor read FOverrideCursor write FOverrideCursor default mcDefault;

When this is not mcDefault, it sets the cursor, regardless of cursor specified at the TCastleUserInterface.Cursor value of the focused control. It even takes precedence over any control using mcForceNone (so it can force the cursor to be visible anyway).

Public property TooltipDelay: Single read FTooltipDelay write FTooltipDelay default DefaultTooltipDelay;

Delay in seconds before showing the tooltip.

Public property TooltipDistance: Cardinal read FTooltipDistance write FTooltipDistance default DefaultTooltipDistance;

This item has no description.

Public property UIScaling: TUIScaling read FUIScaling write SetUIScaling default usNone;

Enable automatic scaling of the UI.

This allows your UI to look correctly on various window sizes (great both for mobile and desktop, where window size may vary wildly). The idea is that you can set UI controls sizes (like TCastleUserInterface.Width, TCastleUserInterface.Height) to a simple constant values. And you should also set appropriate anchors (choose wisely whether to anchor e.g. to left or right, as the simulated window size still has variable aspect ratio). And the result will look good on any actual window size. All the controls will be scaled to fill the same window part. The scaling is actually done by scaling the coordinates, so there's no quality loss, whole rendering just adjusts to the actual window size in a smart way.

See TUIScaling values for precise description how it works.

Public property UIReferenceWidth: Single read FUIReferenceWidth write SetUIReferenceWidth default 0;

Reference width and height to which we fit the container size when UIScaling is usEncloseReferenceSize, usEncloseReferenceSizeAutoOrientation, usFitReferenceSize.

See the documentation of these values and manual to understand how UI scaling works.

You can set both UIReferenceWidth and UIReferenceHeight, or set only one (and leave the other as zero).

Note: If only one of UIReferenceWidth and UIReferenceHeight is non-zero, then these 3 UI scaling modes are equivalent: - usEncloseReferenceSize and - usEncloseReferenceSizeAutoOrientation - usFitReferenceSize When only one UIReferenceWidth and UIReferenceHeight is non-zero, then all these 3 modes just adjust scaling based on this one non-zero reference size.

Public property UIReferenceHeight: Single read FUIReferenceHeight write SetUIReferenceHeight default 0;

This item has no description.

Public property UIExplicitScale: Single read FUIExplicitScale write SetUIExplicitScale default 1.0;

Scale of the container size (as seen by TCastleUserInterface implementations) when UIScaling is usExplicitScale. See usExplicitScale for precise description how this works.

Public property DefaultFont: TCastleAbstractFont read FDefaultFont write FDefaultFont;

Default font (type, size) to be used by all user interface controls. Note that each UI control can customize the used font and/or size using properties TCastleUserInterfaceFont.CustomFont, TCastleUserInterfaceFont.FontSize.

If this is Nil, we use the global font UIFont that is always assigned.

Public property BackgroundEnable: Boolean read FBackgroundEnable write FBackgroundEnable default true;

Before rendering anything else, fill the color buffer with BackgroundColor. By default this is True.

You can set this to False to gain a little speed, if you know you always draw something that fills the whole container. For example:

If you set this to False, but do not draw something else over the entire container, then the screen contents at the beginning are undefined.

Public property BackgroundColor: TCastleColor read FBackgroundColor write FBackgroundColor;

Color that fills the window by default. By default it is DefaultBackgroundColor, which is very dark gray.

Public class property InputInspector: TInputInspector read FInputInspector;

Input (key, touch) to toggle the inspector at any point in the application. By default this is possible in debug builds, using key F8, or pressing 3 fingers for 1 second.

Public property InspectorKey: TKey read GetInspectorKey write SetInspectorKey; deprecated 'use InputInspector';

Warning: this symbol is deprecated: use InputInspector

Use InputInspector.Key now.

Public property View: TCastleView read GetView write SetView;

Current view. Simply assign to this property to change the current view.

In case multiple views are active (only possible if you used the PushView method), this property returns the bottom view (use FrontView to get top view). Setting this property resets whole view stack.

When is it allowed to change the view?

While in theory you can change current view stack (assigning View or using PushView / PopView) at any moment, but remember that stopping the view frees also the view UI. So you should not change the current view stack within events/overriden methods of classes like TCastleUserInterface, TCastleTransform, TCastleBehavior that could be destroyed by the view stop.

The simpler advise is: Assign to View or use PushView / PopView only from the overridden TCastleView methods. Like TMyView.Update or TMyView.Press.

Note that you cannot change current view stack when another change is in progress. That is, you cannot change view from within TMyView.Start/Resume/Pause/Stop.

Public property FrontView: TCastleView read GetFrontView;

The view in the front (top-most view on the stack).

In case you used PushView, this returns the top-most (most recently pushed) view.

If there is only one (or none) view, e.g. because you never used PushView, then this property returns the same thing as View.

Public property ViewStack [const Index: Integer]: TCastleView read GetViewStack;

Access any view within the view stack. Use with indexes between 0 and ViewStackCount - 1. View stack is managed using View / PushView / PopView.

Public property OnSafeBorderChanged: TNotifyEvent read FOnSafeBorderChanged write FOnSafeBorderChanged;

Event called right after SafeBorder changed.


Generated by PasDoc 0.16.0-snapshot.