1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-06-16 10:44:32 +02:00

tabbing, part 2

This commit is contained in:
Ellpeck 2019-08-28 18:58:05 +02:00
parent 5c741a98e9
commit 90d292cd37
4 changed files with 49 additions and 33 deletions

View file

@ -84,16 +84,17 @@ namespace MLEM.Ui.Elements {
public GenericCallback OnSecondaryPressed; public GenericCallback OnSecondaryPressed;
public GenericCallback OnSelected; public GenericCallback OnSelected;
public GenericCallback OnDeselected; public GenericCallback OnDeselected;
public GenericCallback OnMouseEnter; public GenericCallback OnMouseEnter;
public GenericCallback OnMouseExit; public GenericCallback OnMouseExit;
public TextInputCallback OnTextInput; public TextInputCallback OnTextInput;
public GenericCallback OnAreaUpdated; public GenericCallback OnAreaUpdated;
public OtherElementCallback OnMousedElementChanged;
public OtherElementCallback OnSelectedElementChanged;
private UiSystem system; private UiSystem system;
public UiSystem System { public UiSystem System {
get => this.system; get => this.system;
private set { internal set {
this.system = value; this.system = value;
if (this.system != null && !this.HasCustomStyle) if (this.system != null && !this.HasCustomStyle)
this.InitStyle(this.system.Style); this.InitStyle(this.system.Style);
@ -102,7 +103,7 @@ namespace MLEM.Ui.Elements {
protected UiControls Controls => this.System.Controls; protected UiControls Controls => this.System.Controls;
protected InputHandler Input => this.Controls.Input; protected InputHandler Input => this.Controls.Input;
public Point MousePos => this.Input.MousePosition; public Point MousePos => this.Input.MousePosition;
public RootElement Root { get; private set; } public RootElement Root { get; internal set; }
public float Scale => this.Root.ActualScale; public float Scale => this.Root.ActualScale;
public Element Parent { get; private set; } public Element Parent { get; private set; }
public bool IsMouseOver { get; private set; } public bool IsMouseOver { get; private set; }
@ -174,8 +175,10 @@ namespace MLEM.Ui.Elements {
index = this.Children.Count; index = this.Children.Count;
this.Children.Insert(index, element); this.Children.Insert(index, element);
element.Parent = this; element.Parent = this;
element.PropagateRoot(this.Root); element.Propagate(e => {
element.PropagateUiSystem(this.System); e.Root = this.Root;
e.System = this.System;
});
this.SetSortedChildrenDirty(); this.SetSortedChildrenDirty();
this.SetAreaDirty(); this.SetAreaDirty();
return element; return element;
@ -184,8 +187,10 @@ namespace MLEM.Ui.Elements {
public void RemoveChild(Element element) { public void RemoveChild(Element element) {
this.Children.Remove(element); this.Children.Remove(element);
element.Parent = null; element.Parent = null;
element.PropagateRoot(null); element.Propagate(e => {
element.PropagateUiSystem(null); e.Root = null;
e.System = null;
});
this.SetSortedChildrenDirty(); this.SetSortedChildrenDirty();
this.SetAreaDirty(); this.SetAreaDirty();
} }
@ -426,7 +431,7 @@ namespace MLEM.Ui.Elements {
child.Draw(time, batch, alpha * child.DrawAlpha, offset); child.Draw(time, batch, alpha * child.DrawAlpha, offset);
} }
if (this.IsSelected && this.Controls.ShowSelectionIndicator && this.SelectionIndicator != null) { if (this.IsSelected && !this.Controls.SelectedLastElementWithMouse && this.SelectionIndicator != null) {
batch.Draw(this.SelectionIndicator, this.DisplayArea.OffsetCopy(offset), Color.White * alpha); batch.Draw(this.SelectionIndicator, this.DisplayArea.OffsetCopy(offset), Color.White * alpha);
} }
} }
@ -457,22 +462,12 @@ namespace MLEM.Ui.Elements {
public delegate void GenericCallback(Element element); public delegate void GenericCallback(Element element);
internal void PropagateUiSystem(UiSystem system) { public delegate void OtherElementCallback(Element thisElement, Element otherElement);
this.System = system;
foreach (var child in this.Children)
child.PropagateUiSystem(system);
}
internal void PropagateRoot(RootElement root) { internal void Propagate(Action<Element> action) {
this.Root = root; action(this);
foreach (var child in this.Children) foreach (var child in this.Children)
child.PropagateRoot(root); child.Propagate(action);
}
internal void PropagateInput(Keys key, char character) {
this.OnTextInput?.Invoke(this, key, character);
foreach (var child in this.Children)
child.PropagateInput(key, character);
} }
} }

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions; using MLEM.Extensions;
@ -33,6 +34,15 @@ namespace MLEM.Ui.Elements {
// modify the padding so that the scroll bar isn't over top of something else // modify the padding so that the scroll bar isn't over top of something else
this.ScrollBar.PositionOffset -= new Vector2(scrollSize.X + 1, 0); this.ScrollBar.PositionOffset -= new Vector2(scrollSize.X + 1, 0);
this.ChildPadding += new Point(scrollSize.X, 0); this.ChildPadding += new Point(scrollSize.X, 0);
// handle automatic element selection, the scroller needs to scroll to the right location
this.OnSelectedElementChanged += (element, otherElement) => {
if (this.Controls.SelectedLastElementWithMouse)
return;
if (otherElement == null || !otherElement.GetParentTree().Contains(this))
return;
this.ScrollBar.CurrentValue = (otherElement.Area.Bottom - this.Children[1].Area.Top - this.Area.Height / 2) / this.Scale;
};
} }
} }

View file

@ -14,7 +14,7 @@ namespace MLEM.Ui {
public Element MousedElement { get; private set; } public Element MousedElement { get; private set; }
public Element SelectedElement { get; private set; } public Element SelectedElement { get; private set; }
public bool ShowSelectionIndicator; public bool SelectedLastElementWithMouse { get; private set; }
public UiControls(UiSystem system, InputHandler inputHandler = null) { public UiControls(UiSystem system, InputHandler inputHandler = null) {
this.system = system; this.system = system;
@ -34,13 +34,14 @@ namespace MLEM.Ui {
if (mousedNow != null) if (mousedNow != null)
mousedNow.OnMouseEnter?.Invoke(mousedNow); mousedNow.OnMouseEnter?.Invoke(mousedNow);
this.MousedElement = mousedNow; this.MousedElement = mousedNow;
this.system.Propagate(e => e.OnMousedElementChanged?.Invoke(e, mousedNow));
} }
if (this.Input.IsMouseButtonPressed(MouseButton.Left)) { if (this.Input.IsMouseButtonPressed(MouseButton.Left)) {
// select element // select element
var selectedNow = mousedNow != null && mousedNow.CanBeSelected ? mousedNow : null; var selectedNow = mousedNow != null && mousedNow.CanBeSelected ? mousedNow : null;
if (this.SelectedElement != selectedNow) if (this.SelectedElement != selectedNow)
this.SelectElement(selectedNow, false); this.SelectElement(selectedNow, true);
// first action on element // first action on element
if (mousedNow != null) if (mousedNow != null)
@ -61,17 +62,18 @@ namespace MLEM.Ui {
} }
} else if (this.Input.IsKeyPressed(Keys.Tab)) { } else if (this.Input.IsKeyPressed(Keys.Tab)) {
// tab or shift-tab to next or previous element // tab or shift-tab to next or previous element
this.SelectElement(this.GetNextElement(this.Input.IsModifierKeyDown(ModifierKey.Shift)), true); this.SelectElement(this.GetNextElement(this.Input.IsModifierKeyDown(ModifierKey.Shift)), false);
} }
} }
public void SelectElement(Element element, bool show) { public void SelectElement(Element element, bool mouse) {
if (this.SelectedElement != null) if (this.SelectedElement != null)
this.SelectedElement.OnDeselected?.Invoke(this.SelectedElement); this.SelectedElement.OnDeselected?.Invoke(this.SelectedElement);
if (element != null) if (element != null)
element.OnSelected?.Invoke(element); element.OnSelected?.Invoke(element);
this.SelectedElement = element; this.SelectedElement = element;
this.ShowSelectionIndicator = show; this.SelectedLastElementWithMouse = mouse;
this.system.Propagate(e => e.OnSelectedElementChanged?.Invoke(e, element));
} }
public Element GetMousedElement() { public Element GetMousedElement() {

View file

@ -38,7 +38,7 @@ namespace MLEM.Ui {
set { set {
this.style = value; this.style = value;
foreach (var root in this.rootElements) { foreach (var root in this.rootElements) {
root.Element.PropagateUiSystem(this); root.Element.Propagate(e => e.System = this);
root.Element.SetAreaDirty(); root.Element.SetAreaDirty();
} }
} }
@ -62,7 +62,7 @@ namespace MLEM.Ui {
}; };
window.TextInput += (sender, args) => { window.TextInput += (sender, args) => {
foreach (var root in this.rootElements) foreach (var root in this.rootElements)
root.Element.PropagateInput(args.Key, args.Character); root.Element.Propagate(e => e.OnTextInput?.Invoke(e, args.Key, args.Character));
}; };
} }
@ -101,8 +101,10 @@ namespace MLEM.Ui {
if (index < 0 || index > this.rootElements.Count) if (index < 0 || index > this.rootElements.Count)
index = this.rootElements.Count; index = this.rootElements.Count;
this.rootElements.Insert(index, root); this.rootElements.Insert(index, root);
root.Element.PropagateRoot(root); root.Element.Propagate(e => {
root.Element.PropagateUiSystem(this); e.Root = root;
e.System = this;
});
return true; return true;
} }
@ -111,8 +113,10 @@ namespace MLEM.Ui {
if (root == null) if (root == null)
return; return;
this.rootElements.Remove(root); this.rootElements.Remove(root);
root.Element.PropagateRoot(null); root.Element.Propagate(e => {
root.Element.PropagateUiSystem(null); e.Root = null;
e.System = null;
});
} }
public RootElement Get(string name) { public RootElement Get(string name) {
@ -129,6 +133,11 @@ namespace MLEM.Ui {
yield return this.rootElements[i]; yield return this.rootElements[i];
} }
internal void Propagate(Action<Element> action) {
foreach (var root in this.rootElements)
root.Element.Propagate(action);
}
} }
public class RootElement { public class RootElement {