Class TCastleScrollViewCustom

Unit

Declaration

type TCastleScrollViewCustom = class(TCastleUserInterface)

Description

Abstract user interface with a scrollbar. In most cases you want to use TCastleScrollView in your application, which is a more comfortable descendant of this class.

Hierarchy

Overview

Fields

Protected FScrollbarLeft: Boolean;
Public nested const DefaultKeyScrollSpeed = 200.0;
Public nested const DefaultWheelScrollSpeed = 20.0;

Methods

Protected procedure DoScrollChange; virtual;
Protected procedure CustomScrollBarChanged(Sender: TObject);
Protected function GetScroll: Single; virtual; abstract;
Protected procedure SetScroll(Value: Single); virtual; abstract;
Protected function GetScrollStored: Boolean; virtual; abstract;
Protected function GetPageSize: Single; virtual; abstract;
Protected function GetCompleteSize: Single; virtual; abstract;
Public constructor Create(AOwner: TComponent); override;
Public destructor Destroy; override;
Public procedure RenderOverChildren; override;
Public function PropertySections(const PropertyName: String): TPropertySections; override;
Public function Press(const Event: TInputPressRelease): boolean; override;
Public function Release(const Event: TInputPressRelease): boolean; override;
Public function PreviewPress(const Event: TInputPressRelease): boolean; override;
Public function Motion(const Event: TInputMotion): boolean; override;
Public procedure Update(const SecondsPassed: Single; var HandleInput: boolean); override;
Public function EffectiveScrollBarWidth: Single;
Public function ScrollMin: Single;
Public function ScrollMax: Single;

Properties

Protected property ScrollbarVisible: Boolean read FScrollbarVisible;
Public property TintScrollBarInactive: TCastleColor read FTintScrollBarInactive write FTintScrollBarInactive;
Published property KeyScrollSpeed: Single read FKeyScrollSpeed write FKeyScrollSpeed default DefaultKeyScrollSpeed;
Published property WheelScrollSpeed: Single read FWheelScrollSpeed write FWheelScrollSpeed default DefaultWheelScrollSpeed;
Published property ScrollBarWidth: Single read FScrollBarWidth write FScrollBarWidth default 0;
Published property ScrollBarLeft: Boolean read FScrollBarLeft write FScrollBarLeft default false;
Published property EnableDragging: Boolean read FEnableDragging write FEnableDragging default true;
Published property Scroll: Single read GetScroll write SetScroll stored GetScrollStored default 0;
Published property ScrollbarFrame: TCastleImagePersistent read FScrollbarFrame;
Published property ScrollbarSlider: TCastleImagePersistent read FScrollbarSlider;
Published property ScrollbarVerticalMargin: Single read FScrollbarVerticalMargin write SetScrollbarVerticalMargin default 0;
Published property TintScrollBarInactivePersistent: TCastleColorPersistent read FTintScrollBarInactivePersistent ;

Description

Fields

Protected FScrollbarLeft: Boolean;

This item has no description.

Public nested const DefaultKeyScrollSpeed = 200.0;

This item has no description.

Public nested const DefaultWheelScrollSpeed = 20.0;

This item has no description.

Methods

Protected procedure DoScrollChange; virtual;

This item has no description.

Protected procedure CustomScrollBarChanged(Sender: TObject);

This item has no description.

Protected function GetScroll: Single; virtual; abstract;

This item has no description.

Protected procedure SetScroll(Value: Single); virtual; abstract;

This item has no description.

Protected function GetScrollStored: Boolean; virtual; abstract;

This item has no description.

Protected function GetPageSize: Single; virtual; abstract;

How much Scroll is represented by the height of the scrollbar slider. Among other things, this determines how much Scroll changes in response to Page Up and Page Down keys.

Protected function GetCompleteSize: Single; virtual; abstract;

How much Scroll is represented by the height of the entire scrollbar (that is, the height of this TCastleScrollViewCustom instance).

Public constructor Create(AOwner: TComponent); override;

This item has no description.

Public destructor Destroy; override;

This item has no description.

Public procedure RenderOverChildren; override;

This item has no description. Showing description inherited from TCastleUserInterface.RenderOverChildren.

Render a control contents over the children controls. This is analogous to Render, but it executes after children are drawn. You should usually prefer to override Render instead of this method, as the convention is that the parent is underneath children.

You should only override this method (do not call it, it will be called by the engine).

See https://castle-engine.io/manual_2d_ui_custom_drawn.php for examples what you can put here.

Public function PropertySections(const PropertyName: String): TPropertySections; override;

This item has no description. Showing description inherited from TCastleComponent.PropertySections.

Section where to show property in the editor.

Public function Press(const Event: TInputPressRelease): boolean; override;

This item has no description. Showing description inherited from TCastleUserInterface.Press.

Override this method to react to user pressing a key, mouse button or mouse wheel. Return True if the event was handled, which prevents from passing this event to other UI controls.

When implementing in descendants it is best to override it like this:

function TMyControl.Press(const Event: TInputPressRelease): boolean;
begin
  Result := inherited;
  if Result then Exit; // exit if ancestor already handled this event

  if Event.IsKey(keyEnter) then
  begin
    // do something in reaction to Enter key
    ...
    // let engine know that this input event was handled
    Exit(true);
  end;

  if Event.IsMouseButton(buttonLeft) then
  begin
    // do something in reaction to left mouse button press
    ...
    // let engine know that this input event was handled
    Exit(true);
  end;
end;

These events are generated for all UI controls, whether they are considered "interactive" or not. These events are generated for non-interactive controls like TCastleRectangleControl or TCastleLabel as well. For example, these events ignore the TCastleButton.Enabled state, they are generated always (see https://github.com/castle-engine/castle-engine/issues/413 ). Use instead TCastleButton.OnClick to detect clicks on a button in a way that honors the TCastleButton.Enabled state.

When a control returns True from Press, it means it starts to "capture" subsequent mouse events: subsequent mouse moves and release will be send to this control even if mouse will move outside of this control.

The events Press and Release are passed to the parent only after the children had a chance to process this event. Overriding them makes sense if you draw something that "looks clickable" in TCastleUserInterface.Render, which is the standard place you should draw stuff. For example our TCastleButton draws there.

In contrast, the events PreviewPress and PreviewRelease are passed first to the parent control, before children have a chance to process this event. In partcular, overriding them makes sense if you draw something that "looks clickable" in TCastleUserInterface.RenderOverChildren.

Public function Release(const Event: TInputPressRelease): boolean; override;

This item has no description. Showing description inherited from TCastleUserInterface.Release.

Override this method to react to user releasing a key, mouse button. Return True if the event was handled, which prevents from passing this event to other UI controls.

This is counterpart to Press method. See Press for more details.

Note: We'd like this method to also be called when user releases a mouse wheel. But currently releasing of the mouse wheel is not reported now by any backend. Only releasing of keys and mouse buttons is reported.

Public function PreviewPress(const Event: TInputPressRelease): boolean; override;

This item has no description. Showing description inherited from TCastleUserInterface.PreviewPress.

Similar to Press but allows the parent control to preview the event before it is passed to children UI controls.

Public function Motion(const Event: TInputMotion): boolean; override;

This item has no description. Showing description inherited from TCastleUserInterface.Motion.

Motion of mouse or touch.

Public procedure Update(const SecondsPassed: Single; var HandleInput: boolean); override;

This item has no description. Showing description inherited from TCastleUserInterface.Update.

Control may do here anything that must be continuously repeated. E.g. camera handles here falling down due to gravity, rotating model in Examine mode, and many more.

This method may be used, among many other things, to continuously react to the fact that user pressed some key (or mouse button). For example, if holding some key should move some 3D object, you should do something like:

if HandleInput then
begin
  if Container.Pressed[keyArrowRight] then
    Transform.Position := Transform.Position + Vector3(SecondsPassed * 10, 0, 0);
  HandleInput := false;
end;

Instead of directly using a key code, consider also using TInputShortcut that makes the input key nicely configurable. See engine tutorial about handling inputs.

Multiplying movement by SecondsPassed makes your operation frame-rate independent. Object will move by 10 units in a second, regardless of how many FPS your game has.

The code related to HandleInput is important if you write a generally-useful control that should nicely cooperate with all other controls, even when placed on top of them or under them. The correct approach is to only look at pressed keys/mouse buttons if HandleInput is True. Moreover, if you did check that HandleInput is True, and you did actually handle some keys, then you have to set HandleInput := false. This will prevent the other controls (behind the current control) from handling the keys (they will get HandleInput = False). And this is important to avoid doubly-processing the same key press, e.g. if two controls react to the same key, only the one on top should process it.

Note that to handle a single press / release (like "switch light on when pressing a key") you should rather use Press and Release methods. Use this method only for continuous handling (like "holding this key makes the light brighter and brighter").

To understand why such HandleInput approach is needed, realize that the "Update" events are called differently than simple mouse and key events like "Press" and "Release". "Press" and "Release" events return whether the event was somehow "handled", and the container passes them only to the controls under the mouse (decided by TCastleUserInterface.CapturesEventsAtPosition). And as soon as some control says it "handled" the event, other controls (even if under the mouse) will not receive the event.

This approach is not suitable for Update events. Some controls need to do the Update job all the time, regardless of whether the control is under the mouse and regardless of what other controls already did. So all controls (well, all controls that exist, in case of TCastleUserInterface, see TCastleUserInterface.Exists) receive Update calls.

So the "handled" status is passed through HandleInput. If a control is not under the mouse, it will receive HandleInput = False. If a control is under the mouse, it will receive HandleInput = True as long as no other control on top of it didn't already change it to False.

Public function EffectiveScrollBarWidth: Single;

Scroll bar width, either from ScrollBarWidth or Theme.ScrollBarWidth.

Public function ScrollMin: Single;

Minimum sensible value for Scroll, corresponds to scrollbar slider at the top.

Public function ScrollMax: Single;

Maximum sensible value for Scroll, corresponds to scrollbar slider at the bottom.

Properties

Protected property ScrollbarVisible: Boolean read FScrollbarVisible;

This item has no description.

Public property TintScrollBarInactive: TCastleColor read FTintScrollBarInactive write FTintScrollBarInactive;

Color and alpha tint to use when scrollbar is not used. May have some alpha, which makes scrollbar "make itself more opaque", and thus noticeable, when you start dragging. By default it's opaque white, which means that no tint is shown.

Published property KeyScrollSpeed: Single read FKeyScrollSpeed write FKeyScrollSpeed default DefaultKeyScrollSpeed;

Speed of scrolling by arrow keys, in pixels (before UI scaling) per second.

Published property WheelScrollSpeed: Single read FWheelScrollSpeed write FWheelScrollSpeed default DefaultWheelScrollSpeed;

Speed of scrolling by mouse wheel, in pixels (before UI scaling) per event.

Published property ScrollBarWidth: Single read FScrollBarWidth write FScrollBarWidth default 0;

Width of the scroll bar. Value of 0 means to use global default in Theme.ScrollBarWidth.

Published property ScrollBarLeft: Boolean read FScrollBarLeft write FScrollBarLeft default false;

Position of the scroll bar.

False

Scroll bar is located on the right side of the ScrollView.

True

Scroll bar is located on the left side of the ScrollView. Pay attention, that additional space is not reserved for the scroll bar automatically, you have to specify ScrollArea.Translation.X manually, e.g. ScrollArea.Translation := Vector2(ScrollBarWidth + Gap, ScrollArea.Translation.Y).

Published property EnableDragging: Boolean read FEnableDragging write FEnableDragging default true;

Enable scrolling by dragging anywhere in the scroll area. This is usually suitable for mobile devices. Note that this doesn't affect the dragging directly by the scrollbar, which is always enabled.

Published property Scroll: Single read GetScroll write SetScroll stored GetScrollStored default 0;

How much do we scroll. Setting it always clamps the value to a sensible range, between ScrollMin and ScrollMax.

In case of TCastleScrollView, setting this moves the TCastleScrollView.ScrollArea vertical anchor, effectively moving the scrolled children. As such, it is expressed in unscaled pixels (just like TCastleUserInterface.Translation, TCastleUserInterface.Height, TCastleUserInterface.EffectiveHeight...). And it is always synchronized with ScrollArea.Translation.Y.

In case of TCastleScrollViewManual, it can correspond to anything you want. You handle TCastleScrollViewManual.OnChange yourself, and interpret this value in whatever way you want.

Published property ScrollbarFrame: TCastleImagePersistent read FScrollbarFrame;

Customize the image of scrollbar frame, drawn on the right side of this control.

Published property ScrollbarSlider: TCastleImagePersistent read FScrollbarSlider;

Customize the image of scrollbar slider, drawn within ScrollbarFrame.

Published property ScrollbarVerticalMargin: Single read FScrollbarVerticalMargin write SetScrollbarVerticalMargin default 0;

Vertical space between the scrollbar and borders of the scrollview. Can be used e.g. to draw up/down buttons by adding them to the TCastleScrollViewCustom.

TODO: We should add automatic PageUpDown buttons activated by property ButtonsUpDown: Boolean, with gfx customizable by ButtonUp, ButtonDown. Then the property ScrollbarVerticalMargin should be deprecated.

Published property TintScrollBarInactivePersistent: TCastleColorPersistent read FTintScrollBarInactivePersistent ;

TintScrollBarInactive that can be visually edited in Castle Game Engine Editor, Lazarus and Delphi. Normal user code does not need to deal with this, instead read or write TintScrollBarInactive directly.

See also
TintScrollBarInactive
Color and alpha tint to use when scrollbar is not used.

Generated by PasDoc 0.16.0-snapshot.