diff --git a/Blish HUD/Controls/Dropdown.cs b/Blish HUD/Controls/Dropdown.cs
index c172baf4f..fde237a70 100644
--- a/Blish HUD/Controls/Dropdown.cs
+++ b/Blish HUD/Controls/Dropdown.cs
@@ -1,10 +1,12 @@
using System;
+using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Blish_HUD.Input;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MonoGame.Extended.TextureAtlases;
+using nspector.Native.NVAPI2;
namespace Blish_HUD.Controls {
///
@@ -12,47 +14,56 @@ namespace Blish_HUD.Controls {
///
public class Dropdown : Control {
- private class DropdownPanel : Control {
-
- private const int TOOLTIP_HOVER_DELAY = 800;
+ private class DropdownPanel : FlowPanel {
private const int SCROLL_CLOSE_THRESHOLD = 20;
private Dropdown _assocDropdown;
- private int _highlightedItemIndex = -1;
-
- private int HighlightedItemIndex {
- get => _highlightedItemIndex;
- set {
- if (SetProperty(ref _highlightedItemIndex, value)) {
- _hoverTime = 0;
- }
- }
- }
-
- private double _hoverTime;
-
private int _startTop;
private DropdownPanel(Dropdown assocDropdown) {
_assocDropdown = assocDropdown;
- _size = new Point(_assocDropdown.Width, _assocDropdown.Height * _assocDropdown.Items.Count);
- _location = GetPanelLocation();
- _zIndex = Screen.TOOLTIP_BASEZINDEX;
+ _size = new Point(_assocDropdown.Width, _assocDropdown.Height * _assocDropdown.Items.Count);
+ _location = GetPanelLocation();
+ _zIndex = Screen.TOOLTIP_BASEZINDEX;
+ this.BackgroundColor = Color.Black; // Needed as some items have white lines between them otherwise.
+ this.FlowDirection = ControlFlowDirection.SingleTopToBottom;
_startTop = _location.Y;
this.Parent = Graphics.SpriteScreen;
- Input.Mouse.LeftMouseButtonPressed += InputOnMousedOffDropdownPanel;
+ Input.Mouse.LeftMouseButtonPressed += InputOnMousedOffDropdownPanel;
Input.Mouse.RightMouseButtonPressed += InputOnMousedOffDropdownPanel;
+
+ this.AddItems();
+ }
+
+ private void AddItems() {
+ foreach (string itemValue in _assocDropdown.Items) {
+ var dropdownPanelItem = new DropdownPanelItem(itemValue) {
+ Parent = this,
+ Height = _assocDropdown.Height,
+ Width = _assocDropdown.Width
+ };
+
+ dropdownPanelItem.Click += this.DropdownPanelItem_Click;
+ }
+ }
+
+ private void DropdownPanelItem_Click(object sender, MouseEventArgs e) {
+ if (sender is DropdownPanelItem panelItem) {
+ _assocDropdown.SelectedItem = panelItem.Value;
+
+ this.Dispose();
+ }
}
private Point GetPanelLocation() {
var dropdownLocation = _assocDropdown.AbsoluteBounds.Location;
int yUnderDef = Graphics.SpriteScreen.Bottom - (dropdownLocation.Y + _assocDropdown.Height + _size.Y);
- int yAboveDef = Graphics.SpriteScreen.Top + (dropdownLocation.Y - _size.Y);
+ int yAboveDef = Graphics.SpriteScreen.Top + (dropdownLocation.Y - _size.Y);
return yUnderDef > 0 || yUnderDef > yAboveDef
// flip down
@@ -76,30 +87,6 @@ private void InputOnMousedOffDropdownPanel(object sender, MouseEventArgs e) {
}
}
- protected override void OnMouseMoved(MouseEventArgs e) {
- this.HighlightedItemIndex = this.RelativeMousePosition.Y / _assocDropdown.Height;
-
- base.OnMouseMoved(e);
- }
-
- private string GetActiveItem() {
- return _highlightedItemIndex > 0 && _highlightedItemIndex < _assocDropdown.Items.Count
- ? _assocDropdown.Items[_highlightedItemIndex]
- : string.Empty;
- }
-
- private void UpdateHoverTimer(double elapsedMilliseconds) {
- if (_mouseOver) {
- _hoverTime += elapsedMilliseconds;
- } else {
- _hoverTime = 0;
- }
-
- this.BasicTooltipText = _hoverTime > TOOLTIP_HOVER_DELAY
- ? GetActiveItem()
- : string.Empty;
- }
-
private void UpdateDropdownLocation() {
_location = GetPanelLocation();
@@ -108,81 +95,102 @@ private void UpdateDropdownLocation() {
}
}
- public override void DoUpdate(GameTime gameTime) {
- UpdateHoverTimer(gameTime.ElapsedGameTime.TotalMilliseconds);
+ public override void UpdateContainer(GameTime gameTime) {
UpdateDropdownLocation();
}
- protected override void OnClick(MouseEventArgs e) {
- _assocDropdown.SelectedItem = _assocDropdown.Items[this.HighlightedItemIndex];
-
- base.OnClick(e);
-
- Dispose();
- }
-
- protected override void Paint(SpriteBatch spriteBatch, Rectangle bounds) {
- spriteBatch.DrawOnCtrl(this, ContentService.Textures.Pixel, new Rectangle(Point.Zero, _size), Color.Black);
-
- int index = 0;
- foreach (string item in _assocDropdown.Items) {
- if (index == this.HighlightedItemIndex) {
- spriteBatch.DrawOnCtrl(this,
- ContentService.Textures.Pixel,
- new Rectangle(2,
- 2 + _assocDropdown.Height * index,
- _size.X - 12 - _textureArrow.Width,
- _assocDropdown.Height - 4),
- new Color(45, 37, 25, 255));
-
- spriteBatch.DrawStringOnCtrl(this,
- item,
- Content.DefaultFont14,
- new Rectangle(8,
- _assocDropdown.Height * index,
- bounds.Width - 13 - _textureArrow.Width,
- _assocDropdown.Height),
- ContentService.Colors.Chardonnay);
- } else {
- spriteBatch.DrawStringOnCtrl(this,
- item,
- Content.DefaultFont14,
- new Rectangle(8,
- _assocDropdown.Height * index,
- bounds.Width - 13 - _textureArrow.Width,
- _assocDropdown.Height),
- Color.FromNonPremultiplied(239, 240, 239, 255));
+ protected override void DisposeControl() {
+ this.Children?.ToList().ForEach(child => {
+ if (child is DropdownPanelItem panelItem) {
+ panelItem.Click -= this.DropdownPanelItem_Click;
}
- index++;
- }
- }
+ child?.Dispose();
+ });
- protected override void DisposeControl() {
if (_assocDropdown != null) {
_assocDropdown._lastPanel = null;
- _assocDropdown = null;
+ _assocDropdown = null;
}
- Input.Mouse.LeftMouseButtonPressed -= InputOnMousedOffDropdownPanel;
+ Input.Mouse.LeftMouseButtonPressed -= InputOnMousedOffDropdownPanel;
Input.Mouse.RightMouseButtonPressed -= InputOnMousedOffDropdownPanel;
base.DisposeControl();
}
+ }
+
+ private class DropdownPanelItem : Control {
+
+ private const int TOOLTIP_HOVER_DELAY = 800;
+
+ private double _hoverTime;
+
+ public string Value { get; }
+
+ public DropdownPanelItem(string value) {
+ Value = value;
+ this.BackgroundColor = Color.Black;
+ }
+ private void UpdateHoverTimer(double elapsedMilliseconds) {
+ if (_mouseOver) {
+ _hoverTime += elapsedMilliseconds;
+ } else {
+ _hoverTime = 0;
+ }
+
+ this.BasicTooltipText = _hoverTime > TOOLTIP_HOVER_DELAY
+ ? Value
+ : string.Empty;
+ }
+
+ public override void DoUpdate(GameTime gameTime) {
+ UpdateHoverTimer(gameTime.ElapsedGameTime.TotalMilliseconds);
+ }
+
+ protected override void Paint(SpriteBatch spriteBatch, Rectangle bounds) {
+ if (this.MouseOver) {
+ spriteBatch.DrawOnCtrl(this,
+ ContentService.Textures.Pixel,
+ new Rectangle(2,
+ 2,
+ _size.X - 12 - _textureArrow.Width,
+ this.Height - 4),
+ new Color(45, 37, 25, 255));
+
+ spriteBatch.DrawStringOnCtrl(this,
+ Value,
+ Content.DefaultFont14,
+ new Rectangle(8,
+ 0,
+ bounds.Width - 13 - _textureArrow.Width,
+ this.Height),
+ ContentService.Colors.Chardonnay);
+ } else {
+ spriteBatch.DrawStringOnCtrl(this,
+ Value,
+ Content.DefaultFont14,
+ new Rectangle(8,
+ 0,
+ bounds.Width - 13 - _textureArrow.Width,
+ this.Height),
+ Color.FromNonPremultiplied(239, 240, 239, 255));
+ }
+ }
}
public static readonly DesignStandard Standard = new DesignStandard(/* Size */ new Point(250, 27),
- /* PanelOffset */ new Point(5, 2),
+ /* PanelOffset */ new Point(5, 2),
/* ControlOffset */ Control.ControlStandard.ControlOffset);
#region Load Static
private static readonly Texture2D _textureInputBox = Content.GetTexture("input-box");
- private static readonly TextureRegion2D _textureArrow = Resources.Control.TextureAtlasControl.GetRegion("inputboxes/dd-arrow");
+ private static readonly TextureRegion2D _textureArrow = Resources.Control.TextureAtlasControl.GetRegion("inputboxes/dd-arrow");
private static readonly TextureRegion2D _textureArrowActive = Resources.Control.TextureAtlasControl.GetRegion("inputboxes/dd-arrow-active");
-
+
#endregion
#region Events
@@ -225,7 +233,12 @@ public string SelectedItem {
public bool PanelOpen => _lastPanel != null;
private DropdownPanel _lastPanel = null;
- private bool _hadPanel = false;
+ private bool _hadPanel = false;
+
+ ///
+ /// Gets or sets the height of the dropdown panel. A value of -1 indicates that all values should be shown.
+ ///
+ public int PanelHeight { get; set; } = -1;
///
/// Initializes a new instance of the class.
@@ -259,6 +272,10 @@ protected override void OnClick(MouseEventArgs e) {
if (_lastPanel == null && !_hadPanel) {
_lastPanel = DropdownPanel.ShowPanel(this);
+ if (this.PanelHeight != -1) {
+ _lastPanel.Height = this.PanelHeight;
+ _lastPanel.CanScroll = true;
+ }
} else {
_hadPanel = false;
}
@@ -285,12 +302,12 @@ protected override void Paint(SpriteBatch spriteBatch, Rectangle bounds) {
new Rectangle(_size.X - 5, 0, 5, _size.Y),
new Rectangle(_textureInputBox.Width - 5, 0,
5, _textureInputBox.Height));
-
+
// Draw dropdown arrow
spriteBatch.DrawOnCtrl(this,
(this.Enabled && this.MouseOver) ? _textureArrowActive : _textureArrow,
new Rectangle(_size.X - _textureArrow.Width - 5,
- _size.Y / 2 - _textureArrow.Height / 2,
+ _size.Y / 2 - _textureArrow.Height / 2,
_textureArrow.Width,
_textureArrow.Height));