2019-08-12 19:44:16 +02:00
|
|
|
using System;
|
|
|
|
using Microsoft.Xna.Framework;
|
|
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
using MLEM.Extensions;
|
2019-08-13 16:02:29 +02:00
|
|
|
using MLEM.Input;
|
2019-08-12 19:44:16 +02:00
|
|
|
using MLEM.Textures;
|
|
|
|
using MLEM.Ui.Style;
|
|
|
|
|
|
|
|
namespace MLEM.Ui.Elements {
|
|
|
|
public class ScrollBar : Element {
|
|
|
|
|
|
|
|
public NinePatch Background;
|
|
|
|
public NinePatch ScrollerTexture;
|
|
|
|
public Point ScrollerOffset;
|
|
|
|
public Point ScrollerSize;
|
|
|
|
private float maxValue;
|
|
|
|
public float MaxValue {
|
|
|
|
get => this.maxValue;
|
|
|
|
set {
|
|
|
|
this.maxValue = Math.Max(0, value);
|
|
|
|
// force current value to be clamped
|
|
|
|
this.CurrentValue = this.currValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private float currValue;
|
|
|
|
public float CurrentValue {
|
|
|
|
get => this.currValue;
|
|
|
|
set {
|
|
|
|
var val = MathHelper.Clamp(value, 0, this.maxValue);
|
|
|
|
if (this.currValue != val) {
|
|
|
|
this.currValue = val;
|
|
|
|
this.OnValueChanged?.Invoke(this, val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public float StepPerScroll = 1;
|
|
|
|
public ValueChanged OnValueChanged;
|
2019-08-13 16:02:29 +02:00
|
|
|
private bool isMouseHeld;
|
2019-08-12 19:44:16 +02:00
|
|
|
|
|
|
|
public ScrollBar(Anchor anchor, Vector2 size, int scrollerHeight, float maxValue) : base(anchor, size) {
|
|
|
|
this.maxValue = maxValue;
|
|
|
|
this.ScrollerSize = new Point(size.X.Floor(), scrollerHeight);
|
|
|
|
}
|
|
|
|
|
|
|
|
public override void Update(GameTime time) {
|
|
|
|
base.Update(time);
|
2019-08-12 19:46:43 +02:00
|
|
|
var moused = this.System.MousedElement;
|
2019-08-13 16:02:29 +02:00
|
|
|
if (moused == this && this.Input.IsMouseButtonDown(MouseButton.Left)) {
|
|
|
|
this.isMouseHeld = true;
|
|
|
|
} else if (this.isMouseHeld && this.Input.IsMouseButtonUp(MouseButton.Left)) {
|
|
|
|
this.isMouseHeld = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.isMouseHeld) {
|
|
|
|
var internalY = this.MousePos.Y - this.Area.Y;
|
|
|
|
this.CurrentValue = internalY / (float) this.Area.Height * this.MaxValue;
|
|
|
|
}
|
|
|
|
|
2019-08-12 19:46:43 +02:00
|
|
|
if (moused == this.Parent || moused?.Parent == this.Parent) {
|
|
|
|
var scroll = this.Input.LastScrollWheel - this.Input.ScrollWheel;
|
|
|
|
if (scroll != 0)
|
|
|
|
this.CurrentValue += this.StepPerScroll * Math.Sign(scroll);
|
|
|
|
}
|
2019-08-12 19:44:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public override void Draw(GameTime time, SpriteBatch batch, float alpha, Point offset) {
|
|
|
|
batch.Draw(this.Background, this.DisplayArea.OffsetCopy(offset), Color.White * alpha, this.Scale);
|
|
|
|
|
|
|
|
var scrollerPos = new Point(this.DisplayArea.X + offset.X + this.ScrollerOffset.X, this.DisplayArea.Y + offset.Y + this.ScrollerOffset.Y);
|
|
|
|
var scrollerYOffset = (this.currValue / this.maxValue * (this.DisplayArea.Height - this.ScrollerSize.Y * this.Scale)).Floor();
|
|
|
|
var scrollerRect = new Rectangle(scrollerPos + new Point(0, scrollerYOffset), this.ScrollerSize.Multiply(this.Scale));
|
|
|
|
batch.Draw(this.ScrollerTexture, scrollerRect, Color.White * alpha, this.Scale);
|
|
|
|
base.Draw(time, batch, alpha, offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override void InitStyle(UiStyle style) {
|
|
|
|
base.InitStyle(style);
|
|
|
|
this.Background = style.ScrollBarBackground;
|
|
|
|
this.ScrollerTexture = style.ScrollBarScrollerTexture;
|
|
|
|
}
|
|
|
|
|
|
|
|
public delegate void ValueChanged(Element element, float value);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|