osu/osu.Game/Graphics/Containers/OsuScrollContainer.cs

180 lines
5.7 KiB
C#
Raw Normal View History

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
2018-04-13 09:19:50 +00:00
using osu.Framework.Allocation;
using osu.Framework.Graphics;
2018-04-13 09:19:50 +00:00
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
2018-10-02 03:02:47 +00:00
using osu.Framework.Input.Events;
using osuTK;
using osuTK.Graphics;
2018-11-20 07:51:59 +00:00
using osuTK.Input;
2018-04-13 09:19:50 +00:00
namespace osu.Game.Graphics.Containers
{
public class OsuScrollContainer : ScrollContainer<Drawable>
2018-04-13 09:19:50 +00:00
{
public const float SCROLL_BAR_HEIGHT = 10;
public const float SCROLL_BAR_PADDING = 3;
2018-04-13 09:19:50 +00:00
/// <summary>
/// Allows controlling the scroll bar from any position in the container using the right mouse button.
/// Uses the value of <see cref="DistanceDecayOnRightMouseScrollbar"/> to smoothly scroll to the dragged location.
/// </summary>
public bool RightMouseScrollbar = false;
/// <summary>
/// Controls the rate with which the target position is approached when performing a relative drag. Default is 0.02.
/// </summary>
public double DistanceDecayOnRightMouseScrollbar = 0.02;
private bool shouldPerformRightMouseScroll(MouseButtonEvent e) => RightMouseScrollbar && e.Button == MouseButton.Right;
2018-04-13 09:19:50 +00:00
private void scrollFromMouseEvent(MouseEvent e) =>
ScrollTo(Clamp(ToLocalSpace(e.ScreenSpaceMousePosition)[ScrollDim] / DrawSize[ScrollDim]) * Content.DrawSize[ScrollDim], true, DistanceDecayOnRightMouseScrollbar);
2018-04-13 09:19:50 +00:00
private bool rightMouseDragging;
2018-04-13 09:19:50 +00:00
protected override bool IsDragging => base.IsDragging || rightMouseDragging;
2018-04-13 09:19:50 +00:00
public OsuScrollContainer(Direction scrollDirection = Direction.Vertical)
: base(scrollDirection)
{
}
2018-10-02 03:02:47 +00:00
protected override bool OnMouseDown(MouseDownEvent e)
2018-04-13 09:19:50 +00:00
{
if (shouldPerformRightMouseScroll(e))
2018-04-13 09:19:50 +00:00
{
scrollFromMouseEvent(e);
2018-04-13 09:19:50 +00:00
return true;
}
2018-10-02 03:02:47 +00:00
return base.OnMouseDown(e);
2018-04-13 09:19:50 +00:00
}
protected override void OnDrag(DragEvent e)
2018-04-13 09:19:50 +00:00
{
if (rightMouseDragging)
2018-04-13 09:19:50 +00:00
{
scrollFromMouseEvent(e);
return;
2018-04-13 09:19:50 +00:00
}
base.OnDrag(e);
2018-04-13 09:19:50 +00:00
}
2018-10-02 03:02:47 +00:00
protected override bool OnDragStart(DragStartEvent e)
2018-04-13 09:19:50 +00:00
{
2018-10-02 03:02:47 +00:00
if (shouldPerformRightMouseScroll(e))
2018-04-13 09:19:50 +00:00
{
rightMouseDragging = true;
2018-04-13 09:19:50 +00:00
return true;
}
2018-10-02 03:02:47 +00:00
return base.OnDragStart(e);
2018-04-13 09:19:50 +00:00
}
protected override void OnDragEnd(DragEndEvent e)
2018-04-13 09:19:50 +00:00
{
if (rightMouseDragging)
2018-04-13 09:19:50 +00:00
{
rightMouseDragging = false;
return;
2018-04-13 09:19:50 +00:00
}
base.OnDragEnd(e);
2018-04-13 09:19:50 +00:00
}
protected override bool OnScroll(ScrollEvent e)
{
2019-12-17 03:24:59 +00:00
// allow for controlling volume when alt is held.
// mostly for compatibility with osu-stable.
if (e.AltPressed) return false;
return base.OnScroll(e);
}
protected override ScrollbarContainer CreateScrollbar(Direction direction) => new OsuScrollbar(direction);
protected class OsuScrollbar : ScrollbarContainer
{
private Color4 hoverColour;
private Color4 defaultColour;
private Color4 highlightColour;
private readonly Box box;
public OsuScrollbar(Direction scrollDir)
: base(scrollDir)
{
2019-08-21 04:29:50 +00:00
Blending = BlendingParameters.Additive;
CornerRadius = 5;
// needs to be set initially for the ResizeTo to respect minimum size
Size = new Vector2(SCROLL_BAR_HEIGHT);
const float margin = 3;
Margin = new MarginPadding
{
Left = scrollDir == Direction.Vertical ? margin : 0,
Right = scrollDir == Direction.Vertical ? margin : 0,
Top = scrollDir == Direction.Horizontal ? margin : 0,
Bottom = scrollDir == Direction.Horizontal ? margin : 0,
};
Masking = true;
Child = box = new Box { RelativeSizeAxes = Axes.Both };
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Colour = defaultColour = colours.Gray8;
hoverColour = colours.GrayF;
highlightColour = colours.Green;
}
public override void ResizeTo(float val, int duration = 0, Easing easing = Easing.None)
{
Vector2 size = new Vector2(SCROLL_BAR_HEIGHT)
{
[(int)ScrollDirection] = val
};
this.ResizeTo(size, duration, easing);
}
protected override bool OnHover(HoverEvent e)
{
this.FadeColour(hoverColour, 100);
return true;
}
protected override void OnHoverLost(HoverLostEvent e)
{
this.FadeColour(defaultColour, 100);
}
protected override bool OnMouseDown(MouseDownEvent e)
{
if (!base.OnMouseDown(e)) return false;
2020-05-05 01:31:11 +00:00
// note that we are changing the colour of the box here as to not interfere with the hover effect.
box.FadeColour(highlightColour, 100);
return true;
}
protected override void OnMouseUp(MouseUpEvent e)
{
if (e.Button != MouseButton.Left) return;
box.FadeColour(Color4.White, 100);
base.OnMouseUp(e);
}
}
2018-04-13 09:19:50 +00:00
}
}