// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
namespace FlaxEngine.GUI
{
///
/// Base class for container controls that can offset controls in a view (eg. scroll panels).
///
///
[HideInEditor]
public class ScrollableControl : ContainerControl
{
///
/// The view offset. Useful to offset contents of the container (used by the scrollbars and drop panels).
///
protected Float2 _viewOffset;
///
/// Gets current view offset for all the controls (used by the scroll bars).
///
[HideInEditor, NoSerialize]
public Float2 ViewOffset
{
get => _viewOffset;
set => SetViewOffset(ref value);
}
///
/// Sets the view offset.
///
/// The value.
protected virtual void SetViewOffset(ref Float2 value)
{
_viewOffset = value;
OnViewOffsetChanged();
}
///
/// Called when view offset gets changed.
///
protected virtual void OnViewOffsetChanged()
{
}
///
protected override void DrawChildren()
{
// Draw all visible child controls
bool hasViewOffset = !_viewOffset.IsZero;
for (int i = 0; i < _children.Count; i++)
{
var child = _children[i];
if (child.Visible)
{
Matrix3x3 transform = child._cachedTransform;
if (hasViewOffset && child.IsScrollable)
{
transform.M31 += _viewOffset.X;
transform.M32 += _viewOffset.Y;
}
Render2D.PushTransform(ref transform);
child.Draw();
Render2D.PopTransform();
}
}
}
///
public override bool IntersectsChildContent(Control child, Float2 location, out Float2 childSpaceLocation)
{
// Apply offset on scrollable controls
if (child.IsScrollable)
location -= _viewOffset;
return child.IntersectsContent(ref location, out childSpaceLocation);
}
///
public override bool IntersectsContent(ref Float2 locationParent, out Float2 location)
{
// Little workaround to prevent applying offset when performing intersection test with this scrollable control.
// Note that overriden PointFromParent applies view offset.
location = base.PointFromParent(ref locationParent);
return ContainsPoint(ref location);
}
///
public override Float2 PointToParent(ref Float2 location)
{
return base.PointToParent(ref location) + _viewOffset;
}
///
public override Float2 PointFromParent(ref Float2 location)
{
return base.PointFromParent(ref location) - _viewOffset;
}
}
}