1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-11-22 20:58:34 +01: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 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;

View file

@ -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);

View file

@ -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);
}
} }
} }