Class TCastleWindow

Unit

Declaration

type TCastleWindow = class(TComponent)

Description

Window to render everything (3D or 2D) with Castle Game Engine.

You should use this with TCastleView, following https://castle-engine.io/views and the rest of CGE manual. All user interface creation and event handling should be inside some view.

By default, the window is filled with simple color from Container.BackgroundColor.

If you're looking for an analogous Lazarus / Delphi component (that can be placed on a Lazarus / Delphi form) see TCastleControl component. Note that you cannot use both TCastleControl and TCastleWindow within the same application. See https://castle-engine.io/control_on_form .

Deprecated functionality: You can actually add any TCastleUserInterface controls to the Controls property, not only TCastleView descendants.

Hierarchy

  • TObject
  • TPersistent
  • TComponent
  • TCastleWindow

Overview

Methods

Protected function CreateContainer: TWindowContainer; virtual; deprecated 'instead of custom TWindowContainer descendants, use custom TCastleView descendants';
Protected procedure DoUpdate; virtual;
Public function AllowSuspendForInput: boolean; virtual;
Public function Rect: TRectangle;
Public procedure SwapFullScreen; deprecated 'use "FullScreen := not FullScreen"';
Public function TouchesCount: Integer; deprecated 'use Container.TouchesCount';
Public function MousePressed: TCastleMouseButtons;
Public function Controls: TInternalChildrenControls;
Public function GLInitialized: boolean;
Public procedure Open; overload;
Public procedure Open(const Retry: TGLContextRetryOpenFunc); overload;
Public procedure Close(const QuitWhenLastWindowClosed: boolean = true);
Public procedure PostRedisplay; deprecated;
Public procedure Invalidate;
Public procedure MakeCurrent;
Public procedure SaveScreen(const Url: String); overload;
Public function SaveScreen: TRGBImage; overload;
Public function SaveScreen(const SaveRect: TRectangle): TRGBImage; overload;
Public function SaveScreenToGL(const SmoothScaling: boolean = false): TDrawableImage; overload;
Public function SaveScreenToGL(const SaveRect: TRectangle; const SmoothScaling: boolean = false): TDrawableImage; overload;
Public function SaveScreenBuffer: TColorBuffer;
Public procedure SaveScreenDialog(ProposedUrl: String);
Public constructor Create(AOwner: TComponent); override;
Public destructor Destroy; override;
Public function Pressed: TKeysPressed; deprecated 'use Container.Pressed';
Public function Fps: TFramesPerSecond; deprecated 'use Container.Fps';
Public procedure OpenAndRun;
Public procedure ParseParameters;
Public class function ParseParametersHelp: String;
Public function FileDialog(const Title: String; var Url: String; OpenDialog: boolean; FileFilters: TFileFilterList = nil): boolean; overload;
Public function FileDialog(const Title: String; var Url: String; OpenDialog: boolean; const FileFilters: String): boolean; overload;
Public function ColorDialog(var Color: TCastleColor): Boolean; overload;
Public function ColorDialog(var Color: TCastleColorRGB): Boolean; overload;
Public function ColorDialog(var Color: TVector3Byte): Boolean; overload;
Public procedure MessageOK(const S: String; const MessageType: TWindowMessageType);
Public function MessageYesNo(const S: String; const MessageType: TWindowMessageType = mtQuestion): boolean;
Public procedure SetDemoOptions(const ASwapFullScreen_Key: TKey; AClose_KeyString: String; const AFpsShowOnCaption: boolean);

Properties

Public property BorderWidth: Cardinal read FBorderWidth write FBorderWidth default 0;
Public property Container: TWindowContainer read FContainer;
Public property Width: integer read FWidth write SetWidth default WindowDefaultSize;
Public property Height: integer read FHeight write SetHeight default WindowDefaultSize;
Public property Left: integer read FLeft write SetLeft default WindowPositionCenter;
Public property Top : integer read FTop write SetTop default WindowPositionCenter;
Public property FullScreen: boolean read FFullScreenWanted write SetFullScreenWanted default false;
Public property DoubleBuffer: boolean read FDoubleBuffer write FDoubleBuffer default true;
Public property RedBits: Cardinal read FRedBits write FRedBits default 0;
Public property GreenBits: Cardinal read FGreenBits write FGreenBits default 0;
Public property BlueBits: Cardinal read FBlueBits write FBlueBits default 0;
Public property ColorBits: Cardinal read GetColorBits write SetColorBits stored false default 0;
Public property MousePosition: TVector2 read GetMousePosition write SetMousePosition; deprecated 'use Container.MousePressed';
Public property Touches[const Index: Integer]: TTouch read GetTouches; deprecated 'use Container.Touches';
Public property ResizeAllowed: TResizeAllowed read FResizeAllowed write FResizeAllowed default raAllowed;
Public property MinWidth: Integer read FMinWidth write FMinWidth default 100;
Public property MinHeight: Integer read FMinHeight write FMinHeight default 100;
Public property MaxWidth: Integer read FMaxWidth write FMaxWidth default 4000;
Public property MaxHeight: Integer read FMaxHeight write FMaxHeight default 4000;
Public property DepthBits: Cardinal read FDepthBits write FDepthBits default DefaultDepthBits;
Public property StencilBits: Cardinal read FStencilBits write FStencilBits default DefaultStencilBits;
Public property MultiSampling: Cardinal read FMultiSampling write FMultiSampling default 1;
Public property AntiAliasing: TAntiAliasing read FAntiAliasing write SetAntiAliasing default DefaultAntiAliasing;
Public property AlphaBits: Cardinal read FAlphaBits write FAlphaBits default 0;
Public property GtkIconName: String read FGtkIconName write FGtkIconName;
Public property Visible: boolean read FVisible write FVisible default true;
Public property Caption: String read GetPublicCaption write SetPublicCaption;
Public property OnCloseQuery: TContainerObjectEvent read FOnCloseQuery write FOnCloseQuery;
Public property OnDropFiles: TDropFilesFunc read FOnDropFiles write FOnDropFiles;
Public property AutoRedisplay: boolean read FAutoRedisplay write SetAutoRedisplay default true;
Public property MainMenu: TMenu read FMainMenu write SetMainMenu;
Public property MainMenuVisible: boolean read FMainMenuVisible write FMainMenuVisible default true;
Public property OwnsMainMenu: boolean read FOwnsMainMenu write FOwnsMainMenu default true;
Public property OnMenuClick: TMenuClickFunc read FOnMenuClick write FOnMenuClick; deprecated 'use OnMenuItemClick';
Public property OnMenuItemClick: TMenuItemClickEvent read FOnMenuItemClick write FOnMenuItemClick;
Public property Focused: boolean read FFocused;
Public property UserData: Pointer read FUserData write FUserData;
Public property Closed: boolean read FClosed default true;
Public property InternalCursor: TMouseCursor read FCursor write SetCursor default mcDefault;
Public property NamedParameters: TCastleStringList read FNamedParameters;
Public property FpsShowOnCaption: boolean read FFpsShowOnCaption write FFpsShowOnCaption default false;
Public property SwapFullScreen_Key: TKey read FSwapFullScreen_Key write FSwapFullScreen_Key default keyNone;
Public property Close_KeyString: String read FClose_KeyString write FClose_KeyString;
Public property FpsCaptionUpdateDelay: Single read FFpsCaptionUpdateDelay write FFpsCaptionUpdateDelay default DefaultFpsCaptionUpdateDelay;

Description

Methods

Protected function CreateContainer: TWindowContainer; virtual; deprecated 'instead of custom TWindowContainer descendants, use custom TCastleView descendants';

Warning: this symbol is deprecated: instead of custom TWindowContainer descendants, use custom TCastleView descendants

Create a container class for this window. Override this to use a custom container class, e.g. to override some container methods.

Protected procedure DoUpdate; virtual;

This item has no description.

Public function AllowSuspendForInput: boolean; virtual;

Is it allowed to suspend (for an indefinite amount of time) waiting for user input.

Allowing this is a good thing, as it means our process doesn't eat your CPU when it simply waits, doing nothing, for user input. On the other hand, you cannot allow this if you want to do some things continuously, regardless of user input.

The default implementation plays it safe, and does not allow suspending if we have OnUpdate callback defined.

Public function Rect: TRectangle;

Rectangle representing the inside of this container. Always (Left,Bottom) are zero, and (Width,Height) correspond to window sizes.

Public procedure SwapFullScreen; deprecated 'use "FullScreen := not FullScreen"';

Warning: this symbol is deprecated: use "FullScreen := not FullScreen"

Deprecated, instead just do FullScreen := not FullScreen.

Public function TouchesCount: Integer; deprecated 'use Container.TouchesCount';

Warning: this symbol is deprecated: use Container.TouchesCount

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

See also
Touches
Currently active touches on the screen.
Public function MousePressed: TCastleMouseButtons;

Mouse buttons currently pressed. See TCastleContainer.MousePressed for details.

Public function Controls: TInternalChildrenControls;

List of user-interface controls currently active. See TCastleContainer.Controls for details.

Public function GLInitialized: boolean;

Is the OpenGL context initialized. This is equivalent to not Closed, which means we are between an Open and Close calls.

Public procedure Open; overload;

Create the window with associated rendering context and show it.

Call to this method is ignored if the window is already open (if Closed = False).

Exceptions raised
EGLContextNotPossible
If it's not possible to obtain OpenGL context with specified attributes. For example, maybe you set AlphaBits, DepthBits, StencilBits properties too high?

It's guaranteed that when EGLContextNotPossible is raised, the window remains in correct (closed) state. This means that you can catch EGLContextNotPossible and lower some OpenGL buffer requirements and try to open once again. Although it's usually more comfortable to use the overloaded version of Open with Retry callback for this purpose.

This parameterless version of Open automatically turns off multi-sampling (AntiAliasing and MultiSampling properties), and then we turn off stencil buffer (StencilBits), if OpenGL context cannot be initialized. But if it still cannot be initialized, we raise EGLContextNotPossible. You can use overloaded Open version with Retry callback to customize this fallback mechanism, to code which OpenGL context features may be turned off.

Public procedure Open(const Retry: TGLContextRetryOpenFunc); overload;

Open the window with OpenGL context, allowing you to lower the OpenGL context requirements and retry.

If the OpenGL context cannot be initialized, then Retry callback is called. Inside this callback you should either:

  • lower some context requirements (like set MultiSampling to 1 if it was > 1) if possible, and return True to retry, or

  • do not change context requirements and return False to give up.

Note that the parameterless version of Open method actually calls this version, with a default retry callback that turns off AntiAliasing and MultiSampling, and then StencilBits (since all our engine code should be ready that multi-sampling or stencil buffers may not be available). Using your own Retry callback, with this version, allows you to decide which context parameters may be lowered to allow creating a window.

Exceptions raised
EGLContextNotPossible
If it's not possible to obtain requested OpenGL context, and the Retry callback returned False.
Public procedure Close(const QuitWhenLastWindowClosed: boolean = true);

Close window.

  • Calls OnClose.

  • Hides window, destroys it.

  • if this was the only open TCastleWindow window and QuitWhenLastWindowClosed = true then this calls Application.Terminate.

Note that often there's no need to call Close explicitly in your program, because in destructor of this object we call Close, to be sure that window is closed.

TODO: zrobic param boolean CloseFromDestroyQuitWhenLastWindowClosed? As for now Close from destructor is called always with QuitWhenLastWindowClosed = true.

Call to Close is ignored if window is already Closed.

Public procedure PostRedisplay; deprecated;

Warning: this symbol is deprecated.

Deprecated name for Invalidate.

Public procedure Invalidate;

See TCastleContainer.Invalidate.

Public procedure MakeCurrent;

Make the OpenGL context of this window current. Following OpenGL commands will apply to this context, and the RenderContext will also refer to this. When the window is opened, and right before calling any window callback, we always automatically call this, so you should not need to call this method yourself in normal circumstances.

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

Capture the current window contents to an image (file).

These functions take care of making a redraw before capturing screen contents. That's because you can only reliably capture the screen contents of the back buffer (before swap) using OpenGL. In theory, the single-buffer case could be optimized (do not redraw if not needed, that is: if not invalidated), but it's not worth the complication since noone uses single-buffer for normal applications... And also, there is no reliable way to capture screen contents in case of single-buffer.

Note that only capturing the double-buffered windows (the default) is reliable.

Public function SaveScreen: TRGBImage; overload;

This item has no description.

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

This item has no description.

Public function SaveScreenToGL(const SmoothScaling: boolean = false): TDrawableImage; overload;

This item has no description.

Public function SaveScreenToGL(const SaveRect: TRectangle; const SmoothScaling: boolean = false): TDrawableImage; overload;

This item has no description.

Public function SaveScreenBuffer: TColorBuffer;

Color buffer where we draw, and from which it makes sense to grab pixels. Use only if you save the screen using low-level SaveScreen_NoFlush function. Usually, you should save the screen using the simpler SaveScreen method, and then the SaveScreenBuffer is not useful.

Public procedure SaveScreenDialog(ProposedUrl: String);

Asks and saves current screenshot. Asks user where to save the file (using FileDialog, as default URL taking ProposedUrl). If user accepts calls Window.SaveScreen. In case of problems with saving, shows a dialog (doesn't raise exception).

Public constructor Create(AOwner: TComponent); override;

This item has no description.

Public destructor Destroy; override;

This item has no description.

Public function Pressed: TKeysPressed; deprecated 'use Container.Pressed';

Warning: this symbol is deprecated: use Container.Pressed

Keys currently pressed.

Public function Fps: TFramesPerSecond; deprecated 'use Container.Fps';

Warning: this symbol is deprecated: use Container.Fps

Measures application speed.

Public procedure OpenAndRun;

Do Open (initialize rendering context, show the window) followed by Application.Run (run the event loop).

Public procedure ParseParameters;

Parse some command-line options and remove them from Parameters list. See https://castle-engine.io/opengl_options.php for documentaion what these options actually do from user's point of view.

--fullscreen

Sets FullScreen to True.

--window

Sets FullScreen to False.

--geometry WIDTHxHEIGHT<sign>XOFF<sign>YOFF

Sets FullScreen to False and sets window position and size: Width, Height, Left, Top.

--fullscreen-custom WIDTHxHEIGHT

Change desktop resolution by VideoChange and sets FullScreen to True. Changing desktop resolution is not implemented on all platforms.

--pretend-touch-device

Set ApplicationProperties.TouchDevice to true. See touch input documentation.

Exceptions raised
EInvalidParams
When some of our options have invalid arguments.
Public class function ParseParametersHelp: String;

Help text for options handled by ParseParameters.

Returned string may be multiline, but it does not contain the trailing newline (newline char after the last line).

Public function FileDialog(const Title: String; var Url: String; OpenDialog: boolean; FileFilters: TFileFilterList = nil): boolean; overload;

Select a file to open or save, using native (looks familiar on a given system) dialog box. Accepts and returns argument as an URL.

This dialog may also allow user for some typical file-management operations by the way (create some directories, rename some files etc.).

Returns True and sets URL accordingly if user chooses some file and accepts it. Returns False if user cancels.

As with all the model dialog methods here, like FileDialog, ColorDialog, MessageOK, MessageYesNo:

  • The events of this TCastleWindow will not happen while we are inside a modal dialog box.

    We have a special code that temporarily disables all UI controls on the Controls list (so your TCastleUserInterface, TCastleTransform, TCastleView etc. instances will not have their methods, like Update, called).

  • The events of Application and (in case you have multiple windows open) the events of other TCastleWindow may (but do not have to) happen, while the dialog box is open.

    So be prepared there to handle the situation that this window may be "stuck" in a modal dialog box.

Parameters
Title
A dialog title.
URL
Specifies default file as an URL (or simple filename).

Things are designed such that it's reasonable to pass here:

  • URL of last opened/saved file.

  • '' (empty string) if you don't want to suggest anything.

  • Proposed filename (without directory) of new file to save, like 'output.gltf'.

  • Proposed directory of new file to save, like FilenameToUriSafe('c:/tmp/').

  • Proposed filename and directory of new file to save, like FilenameToUriSafe('c:/tmp/output.gltf').

Given URL can be absolute or relative, may include a path, may include a name. If you specify only a path (remember to end it with the slash), then it's the default path where to save the file. If you specify the name (component after final slash), then it's the proposed file name for saving (for OpenDialog, this proposed file name is ignored, since that's more natural for open dialogs).

When saving to a new file, we advise to provide a proposed filename with extension. So e.g. 'output.gltf' or FilenameToUriSafe('c:/tmp/output.gltf').

Do not rely on the FileFilters argument to imply a reasonable extension for the output URL. The filters on FileFilters are used to filter the displayed contents, but it is undefined whether they also help determine the saved file extension. For example, with GTK backend, f you provide FileFilters that contain only *.gltf, and your proposed URL is '', and user types 'aaa' -> then URL is just 'aaa', not 'aaa.gltf'. So it's better to provide proposed URL like 'output.gltf'.

Passing a filename as an URL is also allowed (as everywhere in our engine), it may be changed into an URL on return.

Empty value ('') always means the same as "current directory", guaranteed. So it's equivalent to @linke(UriCurrentPath).

Note that the path must end with a slash. Otherwise '/tmp/blah' would be ambigous (it could mean either file name 'blah' in the dir '/tmp/' dir, or dir '/tmp/blah' without a proposed file name).

OpenDialog
Is this an open (True) or save (False) file dialog.

  • If OpenDialog = True: force the user to only choose existing (and readable) file. The intention is that you can open file indicated by URL, at least for reading. There is no guarantee about it though (it's not possible to guarantee it on a multi-process OS), the only 100% sure way to know that the file can be opened and read is to actually try to do it.

    To directly read a file (as a stream) from the obtained URL you should usually use our CastleDownload.Download function. This way you get a readable stream and you automatically support loading data from the other protocols (http, data etc.) too.

  • If OpenDialog = False: a save dialog. Allows user to select a non-existing file. If user chooses an existing file, some backends may show a warning like "Are you sure you want to overwrite this file?".

    The intention is that directory of the returned file should exist, and you should be able to write files there. But, again, there is no 100% guarantee about it. The only way to be sure whether you can save a file is to actually try to do it.

    To directly write to a file (as a stream) to the obtained URL you should usually use our UrlSaveStream.

FileFilters
A set of file filters to present to user. Pass Nil (default) if you do not want to use file file filters, so user will just always see everything. An overloaded version allows you to pass file filters encoded in a single string, this may be slightly more comfortable for call, see TFileFilterList.AddFiltersFromString for explanation how to encode filters in a string.
Public function FileDialog(const Title: String; var Url: String; OpenDialog: boolean; const FileFilters: String): boolean; overload;

This item has no description.

Public function ColorDialog(var Color: TCastleColor): Boolean; overload;

Choose a color, using native (looks familiar on a given system) dialog box.

Initial value of Color specifies initial color proposed to the user. If user accepts, we return true and set Color accordingly, else we return false (and do not modify Color).

Overloaded version with TCastleColor specifies a color with alpha. But note that only some backends actually allow user to adjust alpha (others leave alpha unchanged). Backends that allow alpha editing now are: Cocoa, Xlib.

Public function ColorDialog(var Color: TCastleColorRGB): Boolean; overload;

This item has no description.

Public function ColorDialog(var Color: TVector3Byte): Boolean; overload;

This item has no description.

Public procedure MessageOK(const S: String; const MessageType: TWindowMessageType);

Show some information and just ask to press "OK", using native (looks familiar on a given system) dialog box.

Public function MessageYesNo(const S: String; const MessageType: TWindowMessageType = mtQuestion): boolean;

Ask a yes/no question, using native (looks familiar on a given system) dialog box.

Public procedure SetDemoOptions(const ASwapFullScreen_Key: TKey; AClose_KeyString: String; const AFpsShowOnCaption: boolean);

Configure some options typically used by "demo" applications.

Properties

Public property BorderWidth: Cardinal read FBorderWidth write FBorderWidth default 0;

Change this only when Closed. This is the width of border of main GtkWindow that will be created in Open, set with gtk_container_set_border_width.

Public property Container: TWindowContainer read FContainer;

This item has no description.

Public property Width: integer read FWidth write SetWidth default WindowDefaultSize;

Size of the window OpenGL area. Together with frame and border sizes, and eventually menu bar size, this determines the final window size.

When the window is open, these are read-only (may only change through internal methods, that is: we'll update Width, Height, Left, Top to reflect current size and position).

MinWidth / MaxWidth / MinHeight / MaxHeight place constraints on these values (rigorously honored when window is open): always MinWidth <= Width <= MaxWidth and MinHeight <= Height <= MaxHeight.

ResizeAllowed places constrains when window manager and user may change window size. In particular, when ResizeAllowed <> raAllowed then window sizes cannot change when window is open.

Note that for some window managers, we cannot always reliably force the size constraints and block resizing on the desktop. If you set rigorous size constraints, or ResizeAllowed <> raAllowed, you may find that window manager still resizes the window. In such cases, we may fake our size a little — Width and Height values may not correspond to actual size as seen on the desktop. This is comfortable, as in such cases you usually want to just ignore window managers limits and just proceed as if your size requirements are satisfied.

Special WindowDefaultSize value of these properties means: at Open, calculate and use some comfortable window size.

TODO: Make it possible to set these properties while the window is open.

Public property Height: integer read FHeight write SetHeight default WindowDefaultSize;

This item has no description.

Public property Left: integer read FLeft write SetLeft default WindowPositionCenter;

Window position on the screen. If one (or both) of them is equal to WindowPositionCenter at the initialization (Open) time, then it will be set to position the window at the screen center.

TODO: Make it possible to set these properties while the window is open.

Public property Top : integer read FTop write SetTop default WindowPositionCenter;

This item has no description.

Public property FullScreen: boolean read FFullScreenWanted write SetFullScreenWanted default false;

Is the window fullscreen.

A fullscreen window has Width, Height, Left, Top set to fill the whole screen. The window style is also, if possible, borderless.

The window size constraints (like MinWidth, MaxWidth, MinHeight, MaxHeight and ResizeAllowed) are ignored, that is: we do not check whether screen size fits inside MinWidth and MaxWidth. If this is True, the window is always fullscreen. However, the sizes visible to your application (exposed in properties Width, Height) are still constrained by MinWidth, MaxWidth, MinHeight, MaxHeight and ResizeAllowed.

It is best to adjust this property before the window is open, this way window will be immediately open in the full-screen size. In the standard case (see https://castle-engine.io/manual_cross_platform.php about a typical initialization) you should place Window.FullScreen := true inside the unit initialization section.

You can also change this property after the window is open. But note that:

  • Some backends require closing + reopening the window to make it fullscreen. So be prepared that changing FullScreen may result in EventClose + EventOpen events, and all OpenGL resources are reloaded. In most cases, engine takes care of everything automatically (all TCastleScene, TCastleUserInterface, TDrawableImage and other resources are automatically reloaded), just be aware that this operation may take a bit of time.

  • For safety (because of the above limitation), changing this property does not have an immediate effect on the window. The actual fullscreen change will happen a bit later, from the message loop.

Public property DoubleBuffer: boolean read FDoubleBuffer write FDoubleBuffer default true;

Should we request and use the double buffer. After every draw, we automatically swap buffers (if DoubleBuffer) or call glFlush (if not DoubleBuffer).

Public property RedBits: Cardinal read FRedBits write FRedBits default 0;

Required red / green / blue color buffer precision for this window. When 0, the default window system color precision will be used.

You can either set them by separate red / green / blue properties. Or you can use ColorBits that reads / writes all three channels bits. Reading ColorBits simply returns the sum of RedBits + GreenBits + BlueBits. Writing ColorBits simply set RedBits and BlueBits to ColorBits div 3, and sets GreenBits to the remainder. This way green channel has always the best resolution (as is usual, since it's perceived most), and the sum is always as requested. This way setting ColorBits to values like 16 or 24 works as expected.

Note that it's also possible to change color resolution by changing the whole screen settings. See TCastleApplication.VideoColorBits and TCastleApplication.VideoChange for this. These properties only request the color resolution for this window, which is less intrusive (you don't change the whole screen) but also may have a smaller chance of success.

Public property GreenBits: Cardinal read FGreenBits write FGreenBits default 0;

This item has no description.

Public property BlueBits: Cardinal read FBlueBits write FBlueBits default 0;

This item has no description.

Public property ColorBits: Cardinal read GetColorBits write SetColorBits stored false default 0;

This item has no description.

Public property MousePosition: TVector2 read GetMousePosition write SetMousePosition; deprecated 'use Container.MousePressed';

Warning: this symbol is deprecated: use Container.MousePressed

Current mouse position. In case of touch devices, this reports the last known position for FingerIndex = 0, and setting this has no effect.

See TTouch.Position for a documentaion how this is expressed.

In all situations the MousePosition is the latest known mouse position. The only exception is within EventMotion (and so, also in OnMotion callback): MousePosition is then the previous known mouse position, while new mouse position is provided as NewMousePosition argument to EventMotion (and OnMotion).

About setting the mouse position:

  • There is no guarantee that the position was set exactly to what was requested. Various backends have their limitations, and position may be rounded, and almost everywhere position will be clamped to the current screen space.

  • It is undefined whether setting mouse position will generate an OnMotion event (just as if the user moved the mouse). Some backends do it, some don't, and there is no way to make it consistent (because backend may report the motion event with delay, so we really don't know whether user moved the mouse or was it caused by code).

  • Setting mouse position is always ignored when the window is closed.

Public property Touches[const Index: Integer]: TTouch read GetTouches; deprecated 'use Container.Touches';

Warning: this symbol is deprecated: use Container.Touches

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 ResizeAllowed: TResizeAllowed read FResizeAllowed write FResizeAllowed default raAllowed;

When (if at all) window size may be changed.

  • raNotAllowed

    Width and Height can only change to honor MinWidth / MaxWidth / MinHeight / MaxHeight constraints. Absolutely nothing else may cause them to change, user cannot resize the window.

    Note that setting the FullScreen property to True works regardless of this. Just don't change FullScreen property if you don't want to. However, Width / Height values will be kept unchanged (they will not be updated to Application.ScreenWidth and Application.ScreenHeight), so from the point of view of you code the raNotAllowed works always.

    You can be sure that EventResize (OnResize) will be called only once, when window is opened (right after initial EventOpen (OnOpen)).

  • raOnlyAtOpen

    Width and Height may be adjusted when the window is opened, by Open call. For example window manager may decide that the size is too large for the current screen. Or when you request FullScreen window and window size has to be adjusted to match current screen size. Also they will always be adjusted to fit in MinWidth / MaxWidth / MinHeight / MaxHeight constraints.

    After opening, window size cannot change anymore. In particular user cannot resize the window (by dragging border or such). After the first EventOpen (OnOpen) call, the window size becomes constant. From the first EventResize (OnResize) the window size is constant, as long as the window remains open.

    You can be sure that EventResize (OnResize) will be called only once, when window is opened (right after initial EventOpen (OnOpen)).

  • raAllowed

    Width and Height may be adjusted at open time, and later user can resize the window too. This is the default value, giving user and window manager the most flexibility.

    You have to be prepared for this, handling OnResize and adjusting stuff like OpenGL viewport and projection matrix.

Public property MinWidth: Integer read FMinWidth write FMinWidth default 100;

Minimum and maximum window sizes. Always

0 < MinWidth <= MaxWidth and
0 < MinHeight <= MaxHeight

We do not allow user to resize the window outside of these constraints.

We also fix window Width and Height to fit within these constraints when you Open the window. We do it regardless of ResizeAllowed (even when it's raNotAllowed).

In other words, these constraints have a higher priority than ResizeAllowed and your desired Width and Height and even FullScreen (setting FullScreen property will stil change the visible sizes, but your perceived sizes will be constrained by this min/max). So you can be sure that (as long as window is open) Width / Height will always fit in these constraints.

Public property MinHeight: Integer read FMinHeight write FMinHeight default 100;

This item has no description.

Public property MaxWidth: Integer read FMaxWidth write FMaxWidth default 4000;

This item has no description.

Public property MaxHeight: Integer read FMaxHeight write FMaxHeight default 4000;

This item has no description.

Public property DepthBits: Cardinal read FDepthBits write FDepthBits default DefaultDepthBits;

Required depth buffer precision. Zero means that we don't need depth buffer at all. We may get depth buffer with more precision than requested (we may even get depth buffer when we set DepthBits = 0), this all depends on graphic card.

Default value is DefaultDepthBits, which is non-zero and a reasonable default for 3D programs that want to work with depth test enabled.

Note that we have a fallback mechanism in case DepthBits is too large: we fallback on DepthBitsFallback then.

Design notes: Why default value is not 0?

  1. Most programs using OpenGL use 3D and so use depth testing. So many programs would have to call something like Window.DepthBits := DefaultDepthBits.

  2. Often graphic cards / window systems / OSes give you an OpenGL context with depth buffer even if you don't need depth buffer. This makes it easy to forget about setting DepthBits to something non-zero, because on your system you may happen to always get some depth buffer.

If you are writing a program that does not need depth buffer you can set Window.DepthBits := 0, to inform OpenGL it doesn't need to allocate any depth buffer.

Public property StencilBits: Cardinal read FStencilBits write FStencilBits default DefaultStencilBits;

Required stencil buffer precision, zero means that stencil buffer is not needed.

Just like with other XxxBits property, we may get more bits than we requested. But we will never get less — if window system will not be able to provide GL context with requested number of bits, Open will raise an error.

Note that after initializing OpenGL context (when opening the window), StencilBits is not updated to the current (provided) stencil buffer bit size. For example, if you requested StencilBits := 8, and you got 16-bits stencil buffer: StencilBits value will still remain 8. This is sensible in case you close the window, tweak some settings and try to open it again. Use glGetInteger(GL_STENCIL_BITS) when window is open to query current (actual) buffer size.

Public property MultiSampling: Cardinal read FMultiSampling write FMultiSampling default 1;

How many samples are required for multi-sampling (anti-aliasing).

Set AntiAliasing instead of this for more comfortable (higher-level) way to turn on multi-sampling (anti-aliasing). Setting AntiAliasing will also set this property.

1 means that no multi-sampling is required. Values larger than 1 mean that we require OpenGL context with multi-sampling capabilities. Various GPUs may support various values (it's a trade-off between quality and speed), try typical values 2 or 4.

You can enable/disable anti-aliasing in your program by code like

if GLFeatures.Multisample then glEnable(GL_MULTISAMPLE);
if GLFeatures.Multisample then glDisable(GL_MULTISAMPLE);

But usually that's not needed, as it is "on" by default (GL_ARB_multisample spec says so) if you requested multi-sampling context (that is, if this property is > 1). See GL_ARB_multisample spec for details: [http://opengl.org/registry/specs/ARB/multisample.txt].

Just like with other XxxBits property, we may get more samples than we requested (e.g. if you request 3, you will most probably get 4). But we will never get less — if window system will not be able to provide GL context with requested number of bits, Open will raise an error. TODO: actually, this may change to be similar to Lazarus TOpenGLControl.MultiSampling, and also be more comfortable — to retry initialization with no multi-sampling. In this case this property will not be changed, to be nice.

You can always read OpenGL GL_SAMPLE_BUFFERS_ARB and GL_SAMPLES_ARB values after initializing OpenGL context, to know exactly how many samples did you actually get, and did you get multi-sampling at all. Actually, we already initialize global CastleGLUtils.GLCurrentMultiSampling for you, you can use this.

Public property AntiAliasing: TAntiAliasing read FAntiAliasing write SetAntiAliasing default DefaultAntiAliasing;

Comfortably turn on/off anti-aliasing.

Setting this property automatically sets also the MultiSampling property. Although it's easy to request multi-sampling by using the MultiSampling property directly, using AntiAliasing is a little more comfortable. You don't have to wonder what are the sensible values of MultiSampling for common GPUs, and we also automatically use NV_multisample_filter_hint for nicer anti-aliasing when possible.

Public property AlphaBits: Cardinal read FAlphaBits write FAlphaBits default 0;

Required number of bits in alpha channel of color buffer. Zero means that alpha channel is not needed.

Just like with other XxxBits property, we may get more bits than we requested. But we will never get less — if window system will not be able to provide GL context with requested number of bits, Open will raise an error.

Public property GtkIconName: String read FGtkIconName write FGtkIconName;

Name of the icon for this window used by GTK 2 backend.

This is simply passed to gtk_window_set_icon_name, see [http://library.gnome.org/devel/gtk/stable/GtkWindow.html#gtk-window-set-icon-name]. This allows you to use an installed icon (in /usr/share/icons/ or ~/.local/share/icons/) for your program. See [http://library.gnome.org/devel/integration-guide/stable/icons.html.en] for short information how and where to install your icons.

It's ignored on non-GTK 2 backends.

Public property Visible: boolean read FVisible write FVisible default true;

Should this window be actually displayed on the desktop. In all normal programs you want to leave this as True, as the main purpose of the window is to actually be visible and interactive on the desktop.

Setting this to False allows you to get an OpenGL context without showing anything on the desktop. This can be used for rendering and capturing OpenGL stuff without showing it on the desktop. One example is the --screenshot option of castle-model-viewer, see [https://castle-engine.io/castle-model-viewer].

If you implement such thing, remember that you should not render and capture the normal front or back buffer contents. OpenGL makes no guarantee that a hidden window will have any allocated memory, so capturing hidden window contents isn't useful (you may get something valid, or you may get random / blank screen, depending on OS and GPU). However, you can create Framebuffer Object on modern GPUs, and capture it's contents. An example code snippet:

{ add CastleGLImages, CastleImages to your uses clause }

var
  ScreenshotRender: TGLRenderToTexture;
  Image: TRGBImage;
begin
  ScreenshotRender := TGLRenderToTexture.Create(Width, Height);
  try
    ScreenshotRender.Buffer := tbNone;
    ScreenshotRender.GLContextOpen;
    ScreenshotRender.RenderBegin;

    { render your stuff here }

    { capture the screen }
    Image := SaveScreen_NoFlush(Rectangle(0, 0, Width, Height),
      ScreenshotRender.ColorBuffer);
    try
      SaveImage(Image, 'aaa.png');
    finally FreeAndNil(Image) end;

    ScreenshotRender.RenderEnd;
  finally FreeAndNil(ScreenshotRender) end;
end;

Public property Caption: String read GetPublicCaption write SetPublicCaption;

Caption of the window. By default it's initialized from ApplicationProperties.Caption or (if empty) ApplicationName. May be changed even when the window is already open.

Public property OnCloseQuery: TContainerObjectEvent read FOnCloseQuery write FOnCloseQuery;

Called when user tries to close the window. This is called when you use window manager features to close the window, like clicking on the "close" icon on the window frame or using Alt+F4 on most desktops. This is not called when you explicitly close the window by calling the Close method.

When this callback is not assigned, we will just let the window be closed. When it's assigned, the window will not closed — you should call here Close explicitly if you want to (for example, after asking user for confirmation "do you really want to quit?").

When handling this event, you must remember that user may try to close our window at any time. E.g. if you're implementing here somehing like showing user text "You cannot quit now" or asking user "Do you really want to quit" remember that while you display such message to user and you're processing events (e.g. looking for keypress "Yes" or "No"), user may try to close your window again.

CastleMessages unit offers some nice routines that you can safely use here, e.g. you can use it inside OnCloseQuery like

if MessageYesNo(Window, 'Are you sure you want to quit?') then Close;

Inside MessageYesNo, when we're processing events, and waiting for user's answer (yes or no), futher OnCloseQuery events will be ignored, so everything will work OK.

This event is also useful if you want to call Close(false) on closing the window (i.e. QuitWhenLastWindowClosed = false). By default, if this event is undefined, we call Close(true) when user tries to close the window.

Public property OnDropFiles: TDropFilesFunc read FOnDropFiles write FOnDropFiles;

Called when user drag and drops file(s) on the window. In case of macOS bundle, this is also called when user opens a document associated with our application by double-clicking.

Note: this is currently supported only by Form and Cocoa backends of TCastleWindow, see https://castle-engine.io/castlewindow_backends .

Public property AutoRedisplay: boolean read FAutoRedisplay write SetAutoRedisplay default true;

Should we automatically redraw the window all the time, without the need for an Invalidate call. If True (the default), render events will be called as often as reasonable on this system, usually 60 times per second.

If your game may have a still screen (nothing animates), then this approach is a little unoptimal, as we use CPU and GPU for drawing, when it's not needed. In such case, you can set this property to False, and make sure that you call Invalidate always when you need to redraw the screen. Note that the engine components always call Invalidate when necessary, so you really only need to call Invalidate yourself if you make custom rendering in some TCastleUserInterface.OnRender.

Public property MainMenu: TMenu read FMainMenu write SetMainMenu;

Menu bar of this window. When not assigned, we have no menu bar.

Note that MainMenu.Caption will be ignored.

You can change this freely while Closed.

You can change this almost freely while not Closed: you can use various properties of TMenuEntry descendants (adding, deleting items from TMenu, changing Caption, Key, KeyString, Checked properties – anything) and you can change value of MainMenu BUT you must not change MainMenu <> nil state when the window is not Closed. I.e. if you called Open with MainMenu = nil, then MainMenu must stay nil unit Close. If you called Open with MainMenu <> nil, then you can assign other MainMenu values while not Closed, but only values <>nil. I.e. you can't set MainMenu to nil if you called Open with MainMenu <> nil. See examples/window/window_menu/ for demo of changing value of MainMenu while window is not Closed.

Note that MainMenu.Enabled is honoured (as well as Enabled for all menu items inside, of course). You can use this to disallow user from clicking on the whole menu. When MainMenu.Enabled = False then menu click is not called (no MenuItem.DoClick, no OnMenuClick, no OnMenuItemClick) when user presses some menu item. When user presses some keyboard shortcut for some menu item, also no menu click is not called (no MenuItem.DoClick, no OnMenuClick, no OnMenuItemClick) and we make normal EventPress.

Disabling MainMenu is useful e.g. during modal dialog box, like MessageOk. This way you can force use to interact with the modal box.

Public property MainMenuVisible: boolean read FMainMenuVisible write FMainMenuVisible default true;

Is MainMenu visible. False means that we do not show main menu bar, but menu key shortcuts should still work. Right now, you can reliably change this only before window is open.

Public property OwnsMainMenu: boolean read FOwnsMainMenu write FOwnsMainMenu default true;

If true then the MainMenu will automatically freed when this TCastleWindow instance is freed.

Public property OnMenuClick: TMenuClickFunc read FOnMenuClick write FOnMenuClick; deprecated 'use OnMenuItemClick';

Warning: this symbol is deprecated: use OnMenuItemClick

User clicked (enabled) menu item (and it wasn't already handled by TMenuItem.DoClick).

By default, menu item handling is passed to TMenuItem.DoClick. Only when it returns False (not handled) then we call this event.

Public property OnMenuItemClick: TMenuItemClickEvent read FOnMenuItemClick write FOnMenuItemClick;

User clicked (enabled) menu item (and it wasn't already handled by TMenuItem.DoClick).

By default, menu item handling is passed to TMenuItem.DoClick. Only when it returns False (not handled) then we call this event.

Public property Focused: boolean read FFocused;

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

Public property UserData: Pointer read FUserData write FUserData;

Place for your pointer, for any purposes. No code in this unit touches the value of this field. This is similar to TComponent.Tag property.

Public property Closed: boolean read FClosed default true;

This item has no description.

Public property InternalCursor: TMouseCursor read FCursor write SetCursor default mcDefault;

Mouse cursor appearance over this window. See TMouseCursor for a list of possible values and their meanings.

Note that this is for internal usage in the engine. In your applications, you should set TCastleUserInterface.Cursor on any UI control (including on TCastleView), never set this property directly.

Public property NamedParameters: TCastleStringList read FNamedParameters;

Named parameters used to initialize this window. Right now not used (were used by NPAPI plugin, may be useful to new web target).

Public property FpsShowOnCaption: boolean read FFpsShowOnCaption write FFpsShowOnCaption default false;

Show current frames per second on window caption. You can modify this property only before calling Open.

Public property SwapFullScreen_Key: TKey read FSwapFullScreen_Key write FSwapFullScreen_Key default keyNone;

Key to use to switch between FullScreen and not FullScreen. Set to keyNone (default) to disable this functionality. Suggested value to enable this functionality is keyF11, this is consistent will fullscreen key in other programs. You can freely modify it at any time, even after calling Open.

The fullscreen is switched by closing it, changing FullScreen property and opening it again. So be sure to have good OnOpen / OnClose implementations: you have to be able to recreate in OnOpen everything that was released in OnClose.

Public property Close_KeyString: String read FClose_KeyString write FClose_KeyString;

Key to use to close the window. Set to '' (default) to disable this functionality. Suggested value to enable this functionality is CharEscape. You can freely modify it at any time, even after calling Open.

Public property FpsCaptionUpdateDelay: Single read FFpsCaptionUpdateDelay write FFpsCaptionUpdateDelay default DefaultFpsCaptionUpdateDelay;

The amount of time (in seconds) between updating Caption with current FPS value. Used when FpsShowOnCaption.

You probably don't want to change this – the default value is synchronized with how often the TFramesPerSecond actually change. So there's no point in making this smaller (you may cause slowdowns, and you will not see anything better).


Generated by PasDoc 0.16.0-snapshot.