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

Added ScrollBar.MouseDragScrolling

Closes #5
This commit is contained in:
Ell 2022-09-13 16:14:36 +02:00
parent d0c805cf18
commit a6fd2c052e
3 changed files with 47 additions and 27 deletions

View file

@ -30,6 +30,7 @@ Additions
- Added some extension methods for querying Anchor types - Added some extension methods for querying Anchor types
- Added Element.AutoSizeAddedAbsolute to allow for more granular control of auto-sizing - Added Element.AutoSizeAddedAbsolute to allow for more granular control of auto-sizing
- Added Element.OnAddedToUi and Element.OnRemovedFromUi - Added Element.OnAddedToUi and Element.OnRemovedFromUi
- Added ScrollBar.MouseDragScrolling
Improvements Improvements
- Allow elements to auto-adjust their size even when their children are aligned oddly - Allow elements to auto-adjust their size even when their children are aligned oddly

View file

@ -68,7 +68,9 @@ namespace Demos {
this.UiSystem.AutoScaleWithScreen = true; this.UiSystem.AutoScaleWithScreen = true;
// create the root panel that all the other components sit on and add it to the ui system // create the root panel that all the other components sit on and add it to the ui system
this.root = new Panel(Anchor.Center, new Vector2(80, 100), Vector2.Zero, false, true); this.root = new Panel(Anchor.Center, new Vector2(80, 100), Vector2.Zero, false, true) {
ScrollBar = {MouseDragScrolling = true}
};
// add the root to the demos' ui // add the root to the demos' ui
this.UiRoot.AddChild(this.root); this.UiRoot.AddChild(this.root);

View file

@ -33,6 +33,16 @@ namespace MLEM.Ui.Elements {
/// The texture of this scroll bar's scroller indicator /// The texture of this scroll bar's scroller indicator
/// </summary> /// </summary>
public StyleProp<NinePatch> ScrollerTexture; public StyleProp<NinePatch> ScrollerTexture;
/// <summary>
/// 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.
/// </summary>
public StyleProp<bool> SmoothScrolling;
/// <summary>
/// The factor with which <see cref="SmoothScrolling"/> happens.
/// </summary>
public StyleProp<float> SmoothScrollFactor;
/// <summary> /// <summary>
/// The scroller's width and height /// The scroller's width and height
/// </summary> /// </summary>
@ -86,7 +96,7 @@ namespace MLEM.Ui.Elements {
/// <summary> /// <summary>
/// This property is true while the user scrolls on the scroll bar using the mouse or touch input /// This property is true while the user scrolls on the scroll bar using the mouse or touch input
/// </summary> /// </summary>
public bool IsBeingScrolled => this.isMouseHeld || this.isDragging || this.isTouchHeld; public bool IsBeingScrolled => this.isMouseScrolling || this.isMouseDragging || this.isTouchDragging || this.isTouchScrolling;
/// <summary> /// <summary>
/// This field determines if this scroll bar should automatically be hidden from a <see cref="Panel"/> if there aren't enough children to allow for scrolling. /// This field determines if this scroll bar should automatically be hidden from a <see cref="Panel"/> if there aren't enough children to allow for scrolling.
/// </summary> /// </summary>
@ -99,18 +109,14 @@ namespace MLEM.Ui.Elements {
!this.Horizontal ? 0 : this.CurrentValue / this.maxValue * (this.DisplayArea.Width - this.ScrollerSize.X * 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)); this.Horizontal ? 0 : this.CurrentValue / this.maxValue * (this.DisplayArea.Height - this.ScrollerSize.Y * this.Scale));
/// <summary> /// <summary>
/// Whether smooth scrolling should be enabled for this scroll bar. /// Whether this scroll bar should allow dragging the mouse over its attached <see cref="Panel"/>'s content while holding the left mouse button to scroll, similarly to how scrolling using touch input works.
/// Smooth scrolling causes the <see cref="CurrentValue"/> to change gradually rather than instantly when scrolling.
/// </summary> /// </summary>
public StyleProp<bool> SmoothScrolling; public bool MouseDragScrolling;
/// <summary>
/// The factor with which <see cref="SmoothScrolling"/> happens.
/// </summary>
public StyleProp<float> SmoothScrollFactor;
private bool isMouseHeld; private bool isMouseScrolling;
private bool isDragging; private bool isMouseDragging;
private bool isTouchHeld; private bool isTouchScrolling;
private bool isTouchDragging;
private float maxValue; private float maxValue;
private float scrollAdded; private float scrollAdded;
private float currValue; private float currValue;
@ -141,18 +147,29 @@ namespace MLEM.Ui.Elements {
// MOUSE INPUT // MOUSE INPUT
var moused = this.Controls.MousedElement; var moused = this.Controls.MousedElement;
if (moused == this && this.Input.WasMouseButtonUp(MouseButton.Left) && this.Input.IsMouseButtonDown(MouseButton.Left)) { var wasMouseUp = this.Input.WasMouseButtonUp(MouseButton.Left);
this.isMouseHeld = true; var isMouseDown = this.Input.IsMouseButtonDown(MouseButton.Left);
if (moused == this && wasMouseUp && isMouseDown) {
this.isMouseScrolling = true;
this.scrollStartOffset = this.TransformInverseAll(this.Input.ViewportMousePosition.ToVector2()) - this.ScrollerPosition; this.scrollStartOffset = this.TransformInverseAll(this.Input.ViewportMousePosition.ToVector2()) - this.ScrollerPosition;
} else if (this.isMouseHeld && !this.Input.IsMouseButtonDown(MouseButton.Left)) { } else if (!isMouseDown) {
this.isMouseHeld = false; this.isMouseScrolling = false;
} }
if (this.isMouseHeld) if (this.isMouseScrolling)
this.ScrollToPos(this.TransformInverseAll(this.Input.ViewportMousePosition.ToVector2())); this.ScrollToPos(this.TransformInverseAll(this.Input.ViewportMousePosition.ToVector2()));
if (!this.Horizontal && moused != null && (moused == this.Parent || moused.GetParentTree().Contains(this.Parent))) { if (!this.Horizontal) {
var scroll = this.Input.LastScrollWheel - this.Input.ScrollWheel; if (moused != null && (moused == this.Parent || moused.GetParentTree().Contains(this.Parent))) {
if (scroll != 0) var scroll = this.Input.LastScrollWheel - this.Input.ScrollWheel;
this.CurrentValue += this.StepPerScroll * Math.Sign(scroll); if (scroll != 0)
this.CurrentValue += this.StepPerScroll * Math.Sign(scroll);
if (this.MouseDragScrolling && moused != this && wasMouseUp && isMouseDown)
this.isMouseDragging = true;
}
if (!isMouseDown)
this.isMouseDragging = false;
if (this.isMouseDragging)
this.CurrentValue -= (this.Input.MousePosition.Y - this.Input.LastMousePosition.Y) / this.Scale;
} }
// TOUCH INPUT // TOUCH INPUT
@ -162,29 +179,29 @@ namespace MLEM.Ui.Elements {
// if the element under the drag's start position is on top of the panel, start dragging // if the element under the drag's start position is on top of the panel, start dragging
var touched = this.Parent.GetElementUnderPos(this.TransformInverseAll(drag.Position)); var touched = this.Parent.GetElementUnderPos(this.TransformInverseAll(drag.Position));
if (touched != null && touched != this) if (touched != null && touched != this)
this.isDragging = true; this.isTouchDragging = true;
// if we're dragging at all, then move the scroller // if we're dragging at all, then move the scroller
if (this.isDragging) if (this.isTouchDragging)
this.CurrentValue -= drag.Delta.Y / this.Scale; this.CurrentValue -= drag.Delta.Y / this.Scale;
} else { } else {
this.isDragging = false; this.isTouchDragging = false;
} }
} }
if (this.Input.ViewportTouchState.Count <= 0) { if (this.Input.ViewportTouchState.Count <= 0) {
// if no touch has occured this tick, then reset the variable // if no touch has occured this tick, then reset the variable
this.isTouchHeld = false; this.isTouchScrolling = false;
} else { } else {
foreach (var loc in this.Input.ViewportTouchState) { foreach (var loc in this.Input.ViewportTouchState) {
var pos = this.TransformInverseAll(loc.Position); var pos = this.TransformInverseAll(loc.Position);
// 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.isTouchScrolling = true;
this.scrollStartOffset = pos - this.ScrollerPosition; 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.isTouchScrolling)
this.ScrollToPos(pos); this.ScrollToPos(pos);
} }
} }