Skip to content

Commit

Permalink
various tooltip features and improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Ellpeck committed Apr 10, 2024
1 parent 556be37 commit e2635bf
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 9 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ Jump to version:

## 6.3.2 (In Development)

### MLEM.Ui
Additions
- Added the ability to set the anchor that should be used when a tooltip attaches to an element or the mouse
- Added the ability to display tooltips using the auto-nav style even when using the mouse

## 6.3.1

No code changes
Expand Down
3 changes: 2 additions & 1 deletion Demos/GameImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ protected override void LoadContent() {
this.activeDemo = demo.Value.Item2.Invoke(this);
this.activeDemo.LoadContent();
},
PositionOffset = new Vector2(0, 1)
PositionOffset = new Vector2(0, 1),
Tooltip = {DisplayInAutoNavMode = true}
});
}

Expand Down
70 changes: 62 additions & 8 deletions MLEM.Ui/Elements/Tooltip.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using Microsoft.Xna.Framework;
using MLEM.Input;
using MLEM.Ui.Style;
using Color = Microsoft.Xna.Framework.Color;
using RectangleF = MLEM.Misc.RectangleF;
#if FNA
using MLEM.Extensions;
#endif
Expand All @@ -23,14 +26,26 @@ public class Tooltip : Panel {
public readonly List<Paragraph> Paragraphs = new List<Paragraph>();

/// <summary>
/// The offset that this tooltip's top left corner should have from the mouse position
/// The offset that this tooltip should have from the mouse position
/// </summary>
public StyleProp<Vector2> MouseOffset;
/// <summary>
/// The offset that this tooltip's top center coordinate should have from the bottom center of the element snapped to when <see cref="DisplayInAutoNavMode"/> is true.
/// The offset that this tooltip should have from the element snapped to when <see cref="DisplayInAutoNavMode"/> is true.
/// </summary>
public StyleProp<Vector2> AutoNavOffset;
/// <summary>
/// The anchor that should be used when this tooltip is displayed using the mouse. The <see cref="MouseOffset"/> will be applied.
/// </summary>
public StyleProp<Anchor> MouseAnchor;
/// <summary>
/// The anchor that should be used when this tooltip is displayed using auto-nav mode. The <see cref="AutoNavOffset"/> will be applied.
/// </summary>
public StyleProp<Anchor> AutoNavAnchor;
/// <summary>
/// If this is <see langword="true"/>, and the mouse is used, the tooltip will attach to the hovered element in a static position using the <see cref="AutoNavOffset"/> and <see cref="AutoNavAnchor"/> properties, rather than following the mouse cursor exactly.
/// </summary>
public StyleProp<bool> UseAutoNavBehaviorForMouse;
/// <summary>
/// The amount of time that the mouse has to be over an element before it appears
/// </summary>
public StyleProp<TimeSpan> Delay;
Expand Down Expand Up @@ -79,6 +94,7 @@ public StyleProp<float> ParagraphWidth {
/// The position that this tooltip should be following (or snapped to) instead of the <see cref="InputHandler.ViewportMousePosition"/>.
/// If this value is unset, <see cref="InputHandler.ViewportMousePosition"/> will be used as the snap position.
/// Note that <see cref="MouseOffset"/> is still applied with this value set.
/// Note that, if <see cref="UseAutoNavBehaviorForMouse"/> is <see langword="true"/>, this value is ignored.
/// </summary>
public virtual Vector2? SnapPosition { get; set; }

Expand Down Expand Up @@ -151,6 +167,9 @@ protected override void InitStyle(UiStyle style) {
this.Texture = this.Texture.OrStyle(style.TooltipBackground);
this.MouseOffset = this.MouseOffset.OrStyle(style.TooltipOffset);
this.AutoNavOffset = this.AutoNavOffset.OrStyle(style.TooltipAutoNavOffset);
this.MouseAnchor = this.MouseAnchor.OrStyle(style.TooltipMouseAnchor);
this.AutoNavAnchor = this.AutoNavAnchor.OrStyle(style.TooltipAutoNavAnchor);
this.UseAutoNavBehaviorForMouse = this.UseAutoNavBehaviorForMouse.OrStyle(style.TooltipUseAutoNavBehaviorForMouse);
this.Delay = this.Delay.OrStyle(style.TooltipDelay);
this.ParagraphTextColor = this.ParagraphTextColor.OrStyle(style.TooltipTextColor);
this.ParagraphTextScale = this.ParagraphTextScale.OrStyle(style.TextScale);
Expand Down Expand Up @@ -201,11 +220,10 @@ public Paragraph AddParagraph(string text, int index = -1) {
public void SnapPositionToMouse() {
Vector2 snapPosition;
if (this.snapElement != null) {
// center our snap position below the snap element
snapPosition = new Vector2(this.snapElement.DisplayArea.Center.X, this.snapElement.DisplayArea.Bottom) + this.AutoNavOffset;
snapPosition.X -= this.DisplayArea.Width / 2F;
snapPosition = this.GetSnapOffset(this.AutoNavAnchor, this.snapElement.DisplayArea, this.AutoNavOffset);
} else {
snapPosition = (this.SnapPosition ?? this.Input.ViewportMousePosition.ToVector2()) + this.MouseOffset.Value;
var mouseBounds = new RectangleF(this.SnapPosition ?? this.Input.ViewportMousePosition.ToVector2(), Vector2.Zero);
snapPosition = this.GetSnapOffset(this.MouseAnchor, mouseBounds, this.MouseOffset);
}

var viewport = this.System.Viewport;
Expand Down Expand Up @@ -255,8 +273,19 @@ public void Remove() {
/// </summary>
/// <param name="elementToHover">The element that should automatically cause the tooltip to appear and disappear when hovered and not hovered, respectively</param>
public void AddToElement(Element elementToHover) {
elementToHover.OnMouseEnter += e => this.Display(e.System, $"{e.GetType().Name}Tooltip");
elementToHover.OnMouseExit += e => this.Remove();
// mouse controls
elementToHover.OnMouseEnter += e => {
if (this.UseAutoNavBehaviorForMouse)
this.snapElement = e;
this.Display(e.System, $"{e.GetType().Name}Tooltip");
};
elementToHover.OnMouseExit += e => {
this.Remove();
if (this.UseAutoNavBehaviorForMouse)
this.snapElement = null;
};

// auto-nav controls
elementToHover.OnSelected += e => {
if (this.DisplayInAutoNavMode && e.Controls.IsAutoNavMode) {
this.snapElement = e;
Expand Down Expand Up @@ -312,5 +341,30 @@ private void UpdateParagraphStyle(Paragraph paragraph) {
paragraph.AutoAdjustWidth = true;
}

private Vector2 GetSnapOffset(Anchor anchor, RectangleF snapBounds, Vector2 offset) {
switch (anchor) {
case Anchor.TopLeft:
return snapBounds.Location - this.DisplayArea.Size - offset;
case Anchor.TopCenter:
return new Vector2(snapBounds.Center.X - this.DisplayArea.Width / 2F, snapBounds.Top - this.DisplayArea.Height) - offset;
case Anchor.TopRight:
return new Vector2(snapBounds.Right + offset.X, snapBounds.Top - this.DisplayArea.Height - offset.Y);
case Anchor.CenterLeft:
return new Vector2(snapBounds.X - this.DisplayArea.Width - offset.X, snapBounds.Center.Y - this.DisplayArea.Height / 2 + offset.Y);
case Anchor.Center:
return snapBounds.Center - this.DisplayArea.Size / 2 + offset;
case Anchor.CenterRight:
return new Vector2(snapBounds.Right, snapBounds.Center.Y - this.DisplayArea.Height / 2) + offset;
case Anchor.BottomLeft:
return new Vector2(snapBounds.X - this.DisplayArea.Width - offset.X, snapBounds.Bottom + offset.Y);
case Anchor.BottomCenter:
return new Vector2(snapBounds.Center.X - this.DisplayArea.Width / 2F, snapBounds.Bottom) + offset;
case Anchor.BottomRight:
return snapBounds.Location + snapBounds.Size + offset;
default:
throw new NotSupportedException($"Tooltip anchors don't support the {anchor} value");
}
}

}
}
3 changes: 3 additions & 0 deletions MLEM.Ui/Style/UiStyle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ public class UiStyle : GenericDataHolder {
/// The offset of the <see cref="Tooltip"/> element's top center coordinate from the bottom center of the element snapped to when <see cref="Tooltip.DisplayInAutoNavMode"/> is true.
/// </summary>
public Vector2 TooltipAutoNavOffset = new Vector2(0, 8);
public Anchor TooltipAutoNavAnchor = Anchor.BottomCenter;

Check warning on line 169 in MLEM.Ui/Style/UiStyle.cs

View workflow job for this annotation

GitHub Actions / build-publish

Missing XML comment for publicly visible type or member 'UiStyle.TooltipAutoNavAnchor'

Check warning on line 169 in MLEM.Ui/Style/UiStyle.cs

View workflow job for this annotation

GitHub Actions / build-publish

Missing XML comment for publicly visible type or member 'UiStyle.TooltipAutoNavAnchor'

Check warning on line 169 in MLEM.Ui/Style/UiStyle.cs

View workflow job for this annotation

GitHub Actions / build-publish

Missing XML comment for publicly visible type or member 'UiStyle.TooltipAutoNavAnchor'

Check warning on line 169 in MLEM.Ui/Style/UiStyle.cs

View workflow job for this annotation

GitHub Actions / build-publish

Missing XML comment for publicly visible type or member 'UiStyle.TooltipAutoNavAnchor'
public Anchor TooltipMouseAnchor = Anchor.BottomRight;

Check warning on line 170 in MLEM.Ui/Style/UiStyle.cs

View workflow job for this annotation

GitHub Actions / build-publish

Missing XML comment for publicly visible type or member 'UiStyle.TooltipMouseAnchor'

Check warning on line 170 in MLEM.Ui/Style/UiStyle.cs

View workflow job for this annotation

GitHub Actions / build-publish

Missing XML comment for publicly visible type or member 'UiStyle.TooltipMouseAnchor'

Check warning on line 170 in MLEM.Ui/Style/UiStyle.cs

View workflow job for this annotation

GitHub Actions / build-publish

Missing XML comment for publicly visible type or member 'UiStyle.TooltipMouseAnchor'
public bool TooltipUseAutoNavBehaviorForMouse;

Check warning on line 171 in MLEM.Ui/Style/UiStyle.cs

View workflow job for this annotation

GitHub Actions / build-publish

Missing XML comment for publicly visible type or member 'UiStyle.TooltipUseAutoNavBehaviorForMouse'

Check warning on line 171 in MLEM.Ui/Style/UiStyle.cs

View workflow job for this annotation

GitHub Actions / build-publish

Missing XML comment for publicly visible type or member 'UiStyle.TooltipUseAutoNavBehaviorForMouse'

Check warning on line 171 in MLEM.Ui/Style/UiStyle.cs

View workflow job for this annotation

GitHub Actions / build-publish

Missing XML comment for publicly visible type or member 'UiStyle.TooltipUseAutoNavBehaviorForMouse'
/// <summary>
/// The color that the text of a <see cref="Tooltip"/> should have
/// </summary>
Expand Down

0 comments on commit e2635bf

Please sign in to comment.