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

added the ability to move roots to front or back

This commit is contained in:
Ellpeck 2019-08-23 22:23:10 +02:00
parent 7ebcbec56b
commit b6d3496987
3 changed files with 54 additions and 52 deletions

View file

@ -116,6 +116,7 @@ namespace MLEM.Ui.Elements {
public float DrawAlpha = 1;
public bool HasCustomStyle;
public bool SetHeightBasedOnChildren;
public bool CanAutoAnchorsAttach = true;
private Rectangle area;
public Rectangle Area {
@ -158,45 +159,27 @@ namespace MLEM.Ui.Elements {
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)
index = this.Children.Count;
this.Children.Insert(index, element);
if (propagateInfo) {
element.Parent = this;
element.PropagateRoot(this.Root);
element.PropagateUiSystem(this.System);
}
element.Parent = this;
element.PropagateRoot(this.Root);
element.PropagateUiSystem(this.System);
this.SetSortedChildrenDirty();
this.SetAreaDirty();
return element;
}
public void RemoveChild(Element element, bool propagateInfo = true) {
public void RemoveChild(Element element) {
this.Children.Remove(element);
if (propagateInfo) {
element.Parent = null;
element.PropagateRoot(null);
element.PropagateUiSystem(null);
}
element.Parent = null;
element.PropagateRoot(null);
element.PropagateUiSystem(null);
this.SetSortedChildrenDirty();
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() {
this.areaDirty = true;
if (this.Anchor >= Anchor.AutoLeft && this.Parent != null)
@ -279,7 +262,7 @@ namespace MLEM.Ui.Elements {
}
if (this.Anchor >= Anchor.AutoLeft) {
var previousChild = this.GetPreviousChild(false);
var previousChild = this.GetPreviousChild(false, false);
if (previousChild != null) {
var prevArea = previousChild.GetAreaForAutoAnchors();
switch (this.Anchor) {
@ -335,7 +318,7 @@ namespace MLEM.Ui.Elements {
return this.Area;
}
public Element GetPreviousChild(bool hiddenAlso) {
public Element GetPreviousChild(bool hiddenAlso, bool unattachableAlso) {
if (this.Parent == null)
return null;
@ -343,6 +326,8 @@ namespace MLEM.Ui.Elements {
foreach (var child in this.Parent.Children) {
if (!hiddenAlso && child.IsHidden)
continue;
if (!unattachableAlso && !child.CanAutoAnchorsAttach)
continue;
if (child == this)
break;
lastChild = child;

View file

@ -25,14 +25,16 @@ namespace MLEM.Ui.Elements {
this.ScrollBar = new ScrollBar(Anchor.TopRight, new Vector2(scrollSize.X, 1), scrollSize.Y, 0) {
StepPerScroll = 10,
OnValueChanged = (element, value) => {
var firstChild = this.Children[0];
// if the first child is the scrollbar, there are no other children
if (firstChild == element)
// if there is only one child, then we have just the scroll bar
if (this.Children.Count == 1)
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
firstChild.PositionOffset = new Vector2(firstChild.PositionOffset.X, -value.Ceil());
this.ForceUpdateArea();
}
},
CanAutoAnchorsAttach = false
};
this.AddChild(this.ScrollBar);
@ -53,19 +55,17 @@ namespace MLEM.Ui.Elements {
if (child is Panel panel && panel.scrollOverflow)
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();
if (this.scrollOverflow) {
var firstChild = this.Children[0];
// if the first child is the scrollbar, then we know there's no other children
if (firstChild == this.ScrollBar)
// if there is only one child, then we have just the scroll bar
if (this.Children.Count == 1)
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
var childrenHeight = lastChild.Area.Bottom - firstChild.Area.Top;
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 (!this.scrollOverflow) {
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)
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) {
if (this.scrollOverflow) {
if (this.scrollOverflow && this.renderTarget != null) {
// draw children onto the render target
batch.GraphicsDevice.SetRenderTarget(this.renderTarget);
batch.GraphicsDevice.Clear(Color.Transparent);

View file

@ -118,22 +118,29 @@ namespace MLEM.Ui {
}
}
public RootElement Add(string name, Element root) {
if (this.IndexOf(name) >= 0)
throw new ArgumentException($"There is already a root element with name {name}");
public RootElement Add(string name, Element element) {
var root = new RootElement(name, element, this);
this.Add(root);
return root;
}
var rootInst = new RootElement(name, root, this);
this.rootElements.Add(rootInst);
root.PropagateRoot(rootInst);
root.PropagateUiSystem(this);
return rootInst;
internal void Add(RootElement root, int index = -1) {
if (this.IndexOf(root.Name) >= 0)
throw new ArgumentException($"There is already a root element with name {root.Name}");
if (index < 0 || index > this.rootElements.Count)
index = this.rootElements.Count;
this.rootElements.Insert(index, root);
root.Element.PropagateRoot(root);
root.Element.PropagateUiSystem(this);
}
public void Remove(string name) {
var index = this.IndexOf(name);
if (index < 0)
var root = this.Get(name);
if (root == null)
return;
this.rootElements.RemoveAt(index);
this.rootElements.Remove(root);
root.Element.PropagateRoot(null);
root.Element.PropagateUiSystem(null);
}
public RootElement Get(string name) {
@ -179,5 +186,15 @@ namespace MLEM.Ui {
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);
}
}
}