mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-26 14:38:34 +01:00
added the ability to move roots to front or back
This commit is contained in:
parent
7ebcbec56b
commit
b6d3496987
3 changed files with 54 additions and 52 deletions
|
@ -116,6 +116,7 @@ namespace MLEM.Ui.Elements {
|
||||||
public float DrawAlpha = 1;
|
public float DrawAlpha = 1;
|
||||||
public bool HasCustomStyle;
|
public bool HasCustomStyle;
|
||||||
public bool SetHeightBasedOnChildren;
|
public bool SetHeightBasedOnChildren;
|
||||||
|
public bool CanAutoAnchorsAttach = true;
|
||||||
|
|
||||||
private Rectangle area;
|
private Rectangle area;
|
||||||
public Rectangle Area {
|
public Rectangle Area {
|
||||||
|
@ -158,45 +159,27 @@ namespace MLEM.Ui.Elements {
|
||||||
this.SetAreaDirty();
|
this.SetAreaDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public T AddChild<T>(T element, int index = -1, bool propagateInfo = true) where T : Element {
|
public T AddChild<T>(T element, int index = -1) where T : Element {
|
||||||
if (index < 0 || index > this.Children.Count)
|
if (index < 0 || index > this.Children.Count)
|
||||||
index = this.Children.Count;
|
index = this.Children.Count;
|
||||||
this.Children.Insert(index, element);
|
this.Children.Insert(index, element);
|
||||||
if (propagateInfo) {
|
|
||||||
element.Parent = this;
|
element.Parent = this;
|
||||||
element.PropagateRoot(this.Root);
|
element.PropagateRoot(this.Root);
|
||||||
element.PropagateUiSystem(this.System);
|
element.PropagateUiSystem(this.System);
|
||||||
}
|
|
||||||
this.SetSortedChildrenDirty();
|
this.SetSortedChildrenDirty();
|
||||||
this.SetAreaDirty();
|
this.SetAreaDirty();
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveChild(Element element, bool propagateInfo = true) {
|
public void RemoveChild(Element element) {
|
||||||
this.Children.Remove(element);
|
this.Children.Remove(element);
|
||||||
if (propagateInfo) {
|
|
||||||
element.Parent = null;
|
element.Parent = null;
|
||||||
element.PropagateRoot(null);
|
element.PropagateRoot(null);
|
||||||
element.PropagateUiSystem(null);
|
element.PropagateUiSystem(null);
|
||||||
}
|
|
||||||
this.SetSortedChildrenDirty();
|
this.SetSortedChildrenDirty();
|
||||||
this.SetAreaDirty();
|
this.SetAreaDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MoveToFront() {
|
|
||||||
if (this.Parent != null) {
|
|
||||||
this.Parent.RemoveChild(this, false);
|
|
||||||
this.Parent.AddChild(this, -1, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void MoveToBack() {
|
|
||||||
if (this.Parent != null) {
|
|
||||||
this.Parent.RemoveChild(this, false);
|
|
||||||
this.Parent.AddChild(this, 0, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAreaDirty() {
|
public void SetAreaDirty() {
|
||||||
this.areaDirty = true;
|
this.areaDirty = true;
|
||||||
if (this.Anchor >= Anchor.AutoLeft && this.Parent != null)
|
if (this.Anchor >= Anchor.AutoLeft && this.Parent != null)
|
||||||
|
@ -279,7 +262,7 @@ namespace MLEM.Ui.Elements {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.Anchor >= Anchor.AutoLeft) {
|
if (this.Anchor >= Anchor.AutoLeft) {
|
||||||
var previousChild = this.GetPreviousChild(false);
|
var previousChild = this.GetPreviousChild(false, false);
|
||||||
if (previousChild != null) {
|
if (previousChild != null) {
|
||||||
var prevArea = previousChild.GetAreaForAutoAnchors();
|
var prevArea = previousChild.GetAreaForAutoAnchors();
|
||||||
switch (this.Anchor) {
|
switch (this.Anchor) {
|
||||||
|
@ -335,7 +318,7 @@ namespace MLEM.Ui.Elements {
|
||||||
return this.Area;
|
return this.Area;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element GetPreviousChild(bool hiddenAlso) {
|
public Element GetPreviousChild(bool hiddenAlso, bool unattachableAlso) {
|
||||||
if (this.Parent == null)
|
if (this.Parent == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -343,6 +326,8 @@ namespace MLEM.Ui.Elements {
|
||||||
foreach (var child in this.Parent.Children) {
|
foreach (var child in this.Parent.Children) {
|
||||||
if (!hiddenAlso && child.IsHidden)
|
if (!hiddenAlso && child.IsHidden)
|
||||||
continue;
|
continue;
|
||||||
|
if (!unattachableAlso && !child.CanAutoAnchorsAttach)
|
||||||
|
continue;
|
||||||
if (child == this)
|
if (child == this)
|
||||||
break;
|
break;
|
||||||
lastChild = child;
|
lastChild = child;
|
||||||
|
|
|
@ -25,14 +25,16 @@ namespace MLEM.Ui.Elements {
|
||||||
this.ScrollBar = new ScrollBar(Anchor.TopRight, new Vector2(scrollSize.X, 1), scrollSize.Y, 0) {
|
this.ScrollBar = new ScrollBar(Anchor.TopRight, new Vector2(scrollSize.X, 1), scrollSize.Y, 0) {
|
||||||
StepPerScroll = 10,
|
StepPerScroll = 10,
|
||||||
OnValueChanged = (element, value) => {
|
OnValueChanged = (element, value) => {
|
||||||
var firstChild = this.Children[0];
|
// if there is only one child, then we have just the scroll bar
|
||||||
// if the first child is the scrollbar, there are no other children
|
if (this.Children.Count == 1)
|
||||||
if (firstChild == element)
|
|
||||||
return;
|
return;
|
||||||
|
// the "real" first child is the scroll bar, which we want to ignore
|
||||||
|
var firstChild = this.Children[1];
|
||||||
// as all children have to be auto-aligned, moving the first one up will move all others
|
// as all children have to be auto-aligned, moving the first one up will move all others
|
||||||
firstChild.PositionOffset = new Vector2(firstChild.PositionOffset.X, -value.Ceil());
|
firstChild.PositionOffset = new Vector2(firstChild.PositionOffset.X, -value.Ceil());
|
||||||
this.ForceUpdateArea();
|
this.ForceUpdateArea();
|
||||||
}
|
},
|
||||||
|
CanAutoAnchorsAttach = false
|
||||||
};
|
};
|
||||||
this.AddChild(this.ScrollBar);
|
this.AddChild(this.ScrollBar);
|
||||||
|
|
||||||
|
@ -53,19 +55,17 @@ namespace MLEM.Ui.Elements {
|
||||||
if (child is Panel panel && panel.scrollOverflow)
|
if (child is Panel panel && panel.scrollOverflow)
|
||||||
throw new NotSupportedException($"A panel that scrolls overflow cannot contain another panel that scrolls overflow ({child})");
|
throw new NotSupportedException($"A panel that scrolls overflow cannot contain another panel that scrolls overflow ({child})");
|
||||||
}
|
}
|
||||||
|
|
||||||
// move the scrollbar to the front so it isn't used for auto-aligning
|
|
||||||
this.ScrollBar.MoveToFront();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
base.ForceUpdateArea();
|
base.ForceUpdateArea();
|
||||||
|
|
||||||
if (this.scrollOverflow) {
|
if (this.scrollOverflow) {
|
||||||
var firstChild = this.Children[0];
|
// if there is only one child, then we have just the scroll bar
|
||||||
// if the first child is the scrollbar, then we know there's no other children
|
if (this.Children.Count == 1)
|
||||||
if (firstChild == this.ScrollBar)
|
|
||||||
return;
|
return;
|
||||||
var lastChild = this.Children[this.Children.Count - 2];
|
// the "real" first child is the scroll bar, which we want to ignore
|
||||||
|
var firstChild = this.Children[1];
|
||||||
|
var lastChild = this.Children[this.Children.Count - 1];
|
||||||
// the max value of the scrollbar is the amount of non-scaled pixels taken up by overflowing components
|
// the max value of the scrollbar is the amount of non-scaled pixels taken up by overflowing components
|
||||||
var childrenHeight = lastChild.Area.Bottom - firstChild.Area.Top;
|
var childrenHeight = lastChild.Area.Bottom - firstChild.Area.Top;
|
||||||
this.ScrollBar.MaxValue = (childrenHeight - this.Area.Height) / this.Scale + this.ChildPadding.Y * 2;
|
this.ScrollBar.MaxValue = (childrenHeight - this.Area.Height) / this.Scale + this.ChildPadding.Y * 2;
|
||||||
|
@ -85,14 +85,14 @@ namespace MLEM.Ui.Elements {
|
||||||
// if we handle overflow, draw using the render target in DrawUnbound
|
// if we handle overflow, draw using the render target in DrawUnbound
|
||||||
if (!this.scrollOverflow) {
|
if (!this.scrollOverflow) {
|
||||||
base.Draw(time, batch, alpha, offset);
|
base.Draw(time, batch, alpha, offset);
|
||||||
} else {
|
} else if (this.renderTarget != null) {
|
||||||
// draw the actual render target (don't apply the alpha here because it's already drawn onto with alpha)
|
// draw the actual render target (don't apply the alpha here because it's already drawn onto with alpha)
|
||||||
batch.Draw(this.renderTarget, this.GetRenderTargetArea().OffsetCopy(offset), Color.White);
|
batch.Draw(this.renderTarget, this.GetRenderTargetArea().OffsetCopy(offset), Color.White);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState = null, SamplerState samplerState = null) {
|
public override void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState = null, SamplerState samplerState = null) {
|
||||||
if (this.scrollOverflow) {
|
if (this.scrollOverflow && this.renderTarget != null) {
|
||||||
// draw children onto the render target
|
// draw children onto the render target
|
||||||
batch.GraphicsDevice.SetRenderTarget(this.renderTarget);
|
batch.GraphicsDevice.SetRenderTarget(this.renderTarget);
|
||||||
batch.GraphicsDevice.Clear(Color.Transparent);
|
batch.GraphicsDevice.Clear(Color.Transparent);
|
||||||
|
|
|
@ -118,22 +118,29 @@ namespace MLEM.Ui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RootElement Add(string name, Element root) {
|
public RootElement Add(string name, Element element) {
|
||||||
if (this.IndexOf(name) >= 0)
|
var root = new RootElement(name, element, this);
|
||||||
throw new ArgumentException($"There is already a root element with name {name}");
|
this.Add(root);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
var rootInst = new RootElement(name, root, this);
|
internal void Add(RootElement root, int index = -1) {
|
||||||
this.rootElements.Add(rootInst);
|
if (this.IndexOf(root.Name) >= 0)
|
||||||
root.PropagateRoot(rootInst);
|
throw new ArgumentException($"There is already a root element with name {root.Name}");
|
||||||
root.PropagateUiSystem(this);
|
if (index < 0 || index > this.rootElements.Count)
|
||||||
return rootInst;
|
index = this.rootElements.Count;
|
||||||
|
this.rootElements.Insert(index, root);
|
||||||
|
root.Element.PropagateRoot(root);
|
||||||
|
root.Element.PropagateUiSystem(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(string name) {
|
public void Remove(string name) {
|
||||||
var index = this.IndexOf(name);
|
var root = this.Get(name);
|
||||||
if (index < 0)
|
if (root == null)
|
||||||
return;
|
return;
|
||||||
this.rootElements.RemoveAt(index);
|
this.rootElements.Remove(root);
|
||||||
|
root.Element.PropagateRoot(null);
|
||||||
|
root.Element.PropagateUiSystem(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RootElement Get(string name) {
|
public RootElement Get(string name) {
|
||||||
|
@ -179,5 +186,15 @@ namespace MLEM.Ui {
|
||||||
this.System = system;
|
this.System = system;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void MoveToFront() {
|
||||||
|
this.System.Remove(this.Name);
|
||||||
|
this.System.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MoveToBack() {
|
||||||
|
this.System.Remove(this.Name);
|
||||||
|
this.System.Add(this, 0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue