mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-25 22:18:34 +01:00
Compare commits
4 commits
df2d102d8e
...
38214a66a3
Author | SHA1 | Date | |
---|---|---|---|
38214a66a3 | |||
a6fd2c052e | |||
d0c805cf18 | |||
55735b4c64 |
4 changed files with 64 additions and 30 deletions
|
@ -29,6 +29,8 @@ Fixes
|
||||||
Additions
|
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 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
|
||||||
|
@ -40,6 +42,7 @@ Fixes
|
||||||
- Fixed paragraphs sometimes not updating their position properly when hidden because they're empty
|
- Fixed paragraphs sometimes not updating their position properly when hidden because they're empty
|
||||||
- Fixed panels sometimes not drawing children that came into view when their positions changed unexpectedly
|
- Fixed panels sometimes not drawing children that came into view when their positions changed unexpectedly
|
||||||
- Fixed UiMarkdownParser not parsing formatting in headings and blockquotes
|
- Fixed UiMarkdownParser not parsing formatting in headings and blockquotes
|
||||||
|
- Fixed Element.OnChildAdded and Element.OnChildRemoved being called for grandchildren when a child is added
|
||||||
|
|
||||||
### MLEM.Data
|
### MLEM.Data
|
||||||
Improvements
|
Improvements
|
||||||
|
|
|
@ -408,13 +408,23 @@ namespace MLEM.Ui.Elements {
|
||||||
public GamepadNextElementCallback GetGamepadNextElement;
|
public GamepadNextElementCallback GetGamepadNextElement;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that is called when a child is added to this element using <see cref="AddChild{T}"/>
|
/// Event that is called when a child is added to this element using <see cref="AddChild{T}"/>
|
||||||
|
/// Note that, while this event is only called for immediate children of this element, <see cref="RootElement.OnElementAdded"/> is called for all children and grandchildren.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public OtherElementCallback OnChildAdded;
|
public OtherElementCallback OnChildAdded;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that is called when a child is removed from this element using <see cref="RemoveChild"/>
|
/// Event that is called when a child is removed from this element using <see cref="RemoveChild"/>.
|
||||||
|
/// Note that, while this event is only called for immediate children of this element, <see cref="RootElement.OnElementRemoved"/> is called for all children and grandchildren.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public OtherElementCallback OnChildRemoved;
|
public OtherElementCallback OnChildRemoved;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Event that is called when this element is added to a <see cref="UiSystem"/>, that is, when this element's <see cref="System"/> is set to a non-<see langword="null"/> value.
|
||||||
|
/// </summary>
|
||||||
|
public GenericCallback OnAddedToUi;
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is called when this element is removed from a <see cref="UiSystem"/>, that is, when this element's <see cref="System"/> is set to <see langword="null"/>.
|
||||||
|
/// </summary>
|
||||||
|
public GenericCallback OnRemovedFromUi;
|
||||||
|
/// <summary>
|
||||||
/// Event that is called when this element's <see cref="Dispose"/> method is called, which also happens in <see cref="Finalize"/>.
|
/// Event that is called when this element's <see cref="Dispose"/> method is called, which also happens in <see cref="Finalize"/>.
|
||||||
/// This event is useful for unregistering global event handlers when this object should be destroyed.
|
/// This event is useful for unregistering global event handlers when this object should be destroyed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -497,9 +507,10 @@ namespace MLEM.Ui.Elements {
|
||||||
element.AndChildren(e => {
|
element.AndChildren(e => {
|
||||||
e.Root = this.Root;
|
e.Root = this.Root;
|
||||||
e.System = this.System;
|
e.System = this.System;
|
||||||
|
e.OnAddedToUi?.Invoke(e);
|
||||||
this.Root?.InvokeOnElementAdded(e);
|
this.Root?.InvokeOnElementAdded(e);
|
||||||
this.OnChildAdded?.Invoke(this, e);
|
|
||||||
});
|
});
|
||||||
|
this.OnChildAdded?.Invoke(this, element);
|
||||||
this.SetSortedChildrenDirty();
|
this.SetSortedChildrenDirty();
|
||||||
element.SetAreaDirty();
|
element.SetAreaDirty();
|
||||||
return element;
|
return element;
|
||||||
|
@ -520,9 +531,10 @@ namespace MLEM.Ui.Elements {
|
||||||
element.AndChildren(e => {
|
element.AndChildren(e => {
|
||||||
e.Root = null;
|
e.Root = null;
|
||||||
e.System = null;
|
e.System = null;
|
||||||
|
e.OnRemovedFromUi?.Invoke(e);
|
||||||
this.Root?.InvokeOnElementRemoved(e);
|
this.Root?.InvokeOnElementRemoved(e);
|
||||||
this.OnChildRemoved?.Invoke(this, e);
|
|
||||||
});
|
});
|
||||||
|
this.OnChildRemoved?.Invoke(this, element);
|
||||||
this.SetSortedChildrenDirty();
|
this.SetSortedChildrenDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,6 +347,7 @@ namespace MLEM.Ui {
|
||||||
root.Element.AndChildren(e => {
|
root.Element.AndChildren(e => {
|
||||||
e.Root = root;
|
e.Root = root;
|
||||||
e.System = this;
|
e.System = this;
|
||||||
|
e.OnAddedToUi?.Invoke(e);
|
||||||
root.InvokeOnElementAdded(e);
|
root.InvokeOnElementAdded(e);
|
||||||
e.SetAreaDirty();
|
e.SetAreaDirty();
|
||||||
});
|
});
|
||||||
|
@ -369,6 +370,7 @@ namespace MLEM.Ui {
|
||||||
root.Element.AndChildren(e => {
|
root.Element.AndChildren(e => {
|
||||||
e.Root = null;
|
e.Root = null;
|
||||||
e.System = null;
|
e.System = null;
|
||||||
|
e.OnRemovedFromUi?.Invoke(e);
|
||||||
root.InvokeOnElementRemoved(e);
|
root.InvokeOnElementRemoved(e);
|
||||||
e.SetAreaDirty();
|
e.SetAreaDirty();
|
||||||
});
|
});
|
||||||
|
@ -570,7 +572,7 @@ namespace MLEM.Ui {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Element.GenericCallback OnElementAdded;
|
public event Element.GenericCallback OnElementAdded;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that is invoked when a <see cref="Element"/> is removed rom this root element of any of its children.
|
/// Event that is invoked when a <see cref="Element"/> is removed rom this root element or any of its children.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Element.GenericCallback OnElementRemoved;
|
public event Element.GenericCallback OnElementRemoved;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Reference in a new issue