1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-05-23 00:53:37 +02:00

Remember the location that a scroll bar scroller was grabbed in when scrolling

This commit is contained in:
Ell 2021-11-14 21:32:13 +01:00
parent 2a7dc119eb
commit 91d34c0a83
2 changed files with 21 additions and 13 deletions

View file

@ -31,6 +31,7 @@ Improvements
- Allow changing the entire ui style for a single element - Allow changing the entire ui style for a single element
- Skip unnecessary area updates for elements with dirty parents - Skip unnecessary area updates for elements with dirty parents
- Calculate panel scroll bar height based on content height - Calculate panel scroll bar height based on content height
- Remember the location that a scroll bar scroller was grabbed in when scrolling
Fixes Fixes
- Fixed VerticalSpace height parameter being an integer - Fixed VerticalSpace height parameter being an integer

View file

@ -3,7 +3,6 @@ using System.Linq;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch; using Microsoft.Xna.Framework.Input.Touch;
using MLEM.Extensions;
using MLEM.Input; using MLEM.Input;
using MLEM.Misc; using MLEM.Misc;
using MLEM.Textures; using MLEM.Textures;
@ -89,6 +88,13 @@ namespace MLEM.Ui.Elements {
/// </summary> /// </summary>
public bool AutoHideWhenEmpty; public bool AutoHideWhenEmpty;
/// <summary> /// <summary>
/// The position that this scroll bar's scroller is currently at.
/// This value takes the <see cref="Element.DisplayArea"/>, as well as the <see cref="Element.Scale"/> into account.
/// </summary>
public Vector2 ScrollerPosition => this.DisplayArea.Location + new Vector2(
!this.Horizontal ? 0 : this.CurrentValue / this.maxValue * (this.DisplayArea.Width - this.ScrollerSize.X * this.Scale),
this.Horizontal ? 0 : this.CurrentValue / this.maxValue * (this.DisplayArea.Height - this.ScrollerSize.Y * this.Scale));
/// <summary>
/// Whether smooth scrolling should be enabled for this scroll bar. /// Whether smooth scrolling should be enabled for this scroll bar.
/// Smooth scrolling causes the <see cref="CurrentValue"/> to change gradually rather than instantly when scrolling. /// Smooth scrolling causes the <see cref="CurrentValue"/> to change gradually rather than instantly when scrolling.
/// </summary> /// </summary>
@ -104,6 +110,7 @@ namespace MLEM.Ui.Elements {
private float maxValue; private float maxValue;
private float scrollAdded; private float scrollAdded;
private float currValue; private float currValue;
private Vector2 scrollStartOffset;
static ScrollBar() { static ScrollBar() {
InputHandler.EnableGestures(GestureType.HorizontalDrag, GestureType.VerticalDrag); InputHandler.EnableGestures(GestureType.HorizontalDrag, GestureType.VerticalDrag);
@ -130,13 +137,15 @@ namespace MLEM.Ui.Elements {
// MOUSE INPUT // MOUSE INPUT
var moused = this.Controls.MousedElement; var moused = this.Controls.MousedElement;
var mousedPos = Vector2.Transform(this.Input.MousePosition.ToVector2(), this.Root.InvTransform);
if (moused == this && this.Controls.Input.IsMouseButtonPressed(MouseButton.Left)) { if (moused == this && this.Controls.Input.IsMouseButtonPressed(MouseButton.Left)) {
this.isMouseHeld = true; this.isMouseHeld = true;
this.scrollStartOffset = mousedPos - this.ScrollerPosition;
} else if (this.isMouseHeld && !this.Controls.Input.IsMouseButtonDown(MouseButton.Left)) { } else if (this.isMouseHeld && !this.Controls.Input.IsMouseButtonDown(MouseButton.Left)) {
this.isMouseHeld = false; this.isMouseHeld = false;
} }
if (this.isMouseHeld) if (this.isMouseHeld)
this.ScrollToPos(this.Input.MousePosition.Transform(this.Root.InvTransform)); this.ScrollToPos(mousedPos);
if (!this.Horizontal && moused != null && (moused == this.Parent || moused.GetParentTree().Contains(this.Parent))) { if (!this.Horizontal && moused != null && (moused == this.Parent || moused.GetParentTree().Contains(this.Parent))) {
var scroll = this.Input.LastScrollWheel - this.Input.ScrollWheel; var scroll = this.Input.LastScrollWheel - this.Input.ScrollWheel;
if (scroll != 0) if (scroll != 0)
@ -168,11 +177,12 @@ namespace MLEM.Ui.Elements {
// if we just started touching and are on top of the scroller, then we should start scrolling // if we just started touching and are on top of the scroller, then we should start scrolling
if (this.DisplayArea.Contains(pos) && !loc.TryGetPreviousLocation(out _)) { if (this.DisplayArea.Contains(pos) && !loc.TryGetPreviousLocation(out _)) {
this.isTouchHeld = true; this.isTouchHeld = true;
this.scrollStartOffset = pos - this.ScrollerPosition;
break; break;
} }
// scroll no matter if we're on the scroller right now // scroll no matter if we're on the scroller right now
if (this.isTouchHeld) if (this.isTouchHeld)
this.ScrollToPos(pos.ToPoint()); this.ScrollToPos(pos);
} }
} }
@ -184,25 +194,22 @@ namespace MLEM.Ui.Elements {
} }
} }
private void ScrollToPos(Point position) { private void ScrollToPos(Vector2 position) {
var (width, height) = this.ScrollerSize * this.Scale;
if (this.Horizontal) { if (this.Horizontal) {
var internalX = position.X - this.Area.X - this.ScrollerSize.X * this.Scale / 2; var offset = this.scrollStartOffset.X >= 0 && this.scrollStartOffset.X <= width ? this.scrollStartOffset.X : width / 2;
this.CurrentValue = internalX / (this.Area.Width - this.ScrollerSize.X * this.Scale) * this.MaxValue; this.CurrentValue = (position.X - this.Area.X - offset) / (this.Area.Width - width) * this.MaxValue;
} else { } else {
var internalY = position.Y - this.Area.Y - this.ScrollerSize.Y * this.Scale / 2; var offset = this.scrollStartOffset.Y >= 0 && this.scrollStartOffset.Y <= height ? this.scrollStartOffset.Y : height / 2;
this.CurrentValue = internalY / (this.Area.Height - this.ScrollerSize.Y * this.Scale) * this.MaxValue; this.CurrentValue = (position.Y - this.Area.Y - offset) / (this.Area.Height - height) * this.MaxValue;
} }
} }
/// <inheritdoc /> /// <inheritdoc />
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
batch.Draw(this.Background, this.DisplayArea, Color.White * alpha, this.Scale); batch.Draw(this.Background, this.DisplayArea, Color.White * alpha, this.Scale);
if (this.MaxValue > 0) { if (this.MaxValue > 0) {
var scrollerOffset = new Vector2( var scrollerRect = new RectangleF(this.ScrollerPosition, this.ScrollerSize * this.Scale);
!this.Horizontal ? 0 : this.CurrentValue / this.maxValue * (this.DisplayArea.Width - this.ScrollerSize.X * this.Scale),
this.Horizontal ? 0 : this.CurrentValue / this.maxValue * (this.DisplayArea.Height - this.ScrollerSize.Y * this.Scale));
var scrollerRect = new RectangleF(this.DisplayArea.Location + scrollerOffset, this.ScrollerSize * this.Scale);
batch.Draw(this.ScrollerTexture, scrollerRect, Color.White * alpha, this.Scale); batch.Draw(this.ScrollerTexture, scrollerRect, Color.White * alpha, this.Scale);
} }
base.Draw(time, batch, alpha, blendState, samplerState, matrix); base.Draw(time, batch, alpha, blendState, samplerState, matrix);