Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 66 additions & 1 deletion Events Module/BasicSettingsView.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Blish_HUD.Controls;
using Blish_HUD;
using Blish_HUD.Controls;
using Blish_HUD.Graphics.UI;
using Blish_HUD.Settings;
using Microsoft.Xna.Framework;

namespace Events_Module {
Expand All @@ -14,6 +16,69 @@ protected override void Build(Container buildPanel) {
};

setPosition.Click += SetPosition_Click;

var notificationToggle = new Checkbox() {
Text = "Enable Notifications",
Checked = EventsModule.ModuleInstance.NotificationsEnabled,
Parent = buildPanel,
Location = new Point(32, setPosition.Bottom + 20)
};

var chimeToggle = new Checkbox {
Text = "Mute Notifications",
Checked = !EventsModule.ModuleInstance.ChimeEnabled,
Parent = buildPanel,
Location = new Point(notificationToggle.Right + 20, notificationToggle.Top)
};

var preTimeLabel = new Label() {
Text = "Pre-Time (min):",
Parent = buildPanel,
Location = new Point(32, notificationToggle.Bottom + 20),
AutoSizeWidth = true
};

var preTimeTextBox = new TextBox() {
Parent = buildPanel,
Location = new Point(preTimeLabel.Right + 10, preTimeLabel.Top - 5),
Width = 100,
Text = EventsModule.ModuleInstance.NotificationPreTime,
BasicTooltipText = "Comma-separated minutes before event (e.g., 15, 5, 1)"
};

var durationLabel = new Label() {
Text = "Duration (sec):",
Parent = buildPanel,
Location = new Point(preTimeTextBox.Right + 20, preTimeLabel.Top),
AutoSizeWidth = true
};

var durationTextBox = new TextBox() {
Parent = buildPanel,
Location = new Point(durationLabel.Right + 10, durationLabel.Top - 5),
Width = 60,
Text = EventsModule.ModuleInstance.NotificationDuration.ToString(),
BasicTooltipText = "Show notification for X seconds"
};

var showCornerIconToggle = new Checkbox {
Text = "Show Corner Icon",
Checked = EventsModule.ModuleInstance.ShowCornerIcon,
Parent = buildPanel,
Location = new Point(32, preTimeLabel.Bottom + 20)
};

notificationToggle.CheckedChanged += delegate (object sender, CheckChangedEvent e) { EventsModule.ModuleInstance.NotificationsEnabled = e.Checked; };
chimeToggle.CheckedChanged += delegate (object sender, CheckChangedEvent e) { EventsModule.ModuleInstance.ChimeEnabled = !e.Checked; };
showCornerIconToggle.CheckedChanged += delegate (object sender, CheckChangedEvent e) { EventsModule.ModuleInstance.ShowCornerIcon = e.Checked; };
preTimeTextBox.TextChanged += delegate (object sender, System.EventArgs e) {
EventsModule.ModuleInstance.NotificationPreTime = preTimeTextBox.Text;
};
durationTextBox.TextChanged += delegate {
if (int.TryParse(durationTextBox.Text, out int dur) && dur > 0) {
EventsModule.ModuleInstance.NotificationDuration = dur;
}
};
}

private void SetPosition_Click(object sender, Blish_HUD.Input.MouseEventArgs e) => EventsModule.ModuleInstance.ShowSetNotificationPositions();
Expand Down
13 changes: 12 additions & 1 deletion Events Module/EventNotification.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using Blish_HUD;
using Blish_HUD;
using Blish_HUD.Content;
using Blish_HUD.Controls;
using Events_Module.Properties;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;

namespace Events_Module {
public class EventNotification : Container {
Expand All @@ -26,6 +27,7 @@ static EventNotification() {
private readonly AsyncTexture2D _icon;

private static int _visibleNotifications = 0;
private static readonly List<EventNotification> _activeNotifications = new List<EventNotification>();

private EventNotification(string title, AsyncTexture2D icon, string message, string waypoint) {
string tooltipText = Resources.Notification_Tooltip;
Expand Down Expand Up @@ -59,6 +61,7 @@ private EventNotification(string title, AsyncTexture2D icon, string message, str
};

_visibleNotifications++;
_activeNotifications.Add(this);

this.RightMouseButtonReleased += delegate { this.Dispose(); };
this.LeftMouseButtonReleased += delegate {
Expand Down Expand Up @@ -125,8 +128,16 @@ public static void ShowNotification(string title, AsyncTexture2D icon, string me
notif.Show(duration);
}

public static void ClearAll() {
var current = new List<EventNotification>(_activeNotifications);
foreach (var notif in current) {
notif.Dispose();
}
}

protected override void DisposeControl() {
_visibleNotifications--;
_activeNotifications.Remove(this);

base.DisposeControl();
}
Expand Down
145 changes: 143 additions & 2 deletions Events Module/EventsModule.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics;
Expand Down Expand Up @@ -47,11 +47,18 @@ public class EventsModule : Module {
private SettingCollection _watchCollection;
private SettingEntry<bool> _settingNotificationsEnabled;
private SettingEntry<bool> _settingChimeEnabled;
private SettingEntry<string> _settingNotificationPreTime;
private SettingEntry<int> _settingNotificationDuration;
private SettingEntry<bool> _settingShowCornerIcon;

private SettingEntry<Point> _settingNotificationsPosition;

private Texture2D _textureWatch;
private Texture2D _textureWatchActive;
private Texture2D _textureClockIcon;

private CornerIcon _eventsCornerIcon;
private ContextMenuStrip _eventsContextMenu;

public bool NotificationsEnabled {
get => _settingNotificationsEnabled.Value;
Expand All @@ -63,6 +70,21 @@ public bool ChimeEnabled {
set => _settingChimeEnabled.Value = value;
}

public string NotificationPreTime {
get => _settingNotificationPreTime.Value;
set => _settingNotificationPreTime.Value = value;
}

public bool ShowCornerIcon {
get => _settingShowCornerIcon.Value;
set => _settingShowCornerIcon.Value = value;
}

public int NotificationDuration {
get => _settingNotificationDuration.Value;
set => _settingNotificationDuration.Value = value;
}

public Point NotificationPosition {
get => _settingNotificationsPosition.Value;
set => _settingNotificationsPosition.Value = value;
Expand All @@ -78,6 +100,9 @@ protected override void DefineSettings(SettingCollection settings) {

_settingNotificationsEnabled = selfManagedSettings.DefineSetting(@"notificationsEnabled", true);
_settingChimeEnabled = selfManagedSettings.DefineSetting(@"chimeEnabled", true);
_settingNotificationPreTime = selfManagedSettings.DefineSetting(@"notificationPreTime", "15");
_settingNotificationDuration = selfManagedSettings.DefineSetting(@"notificationDuration", 10);
_settingShowCornerIcon = selfManagedSettings.DefineSetting(@"showCornerIcon", true);

_settingNotificationsPosition = selfManagedSettings.DefineSetting("notificationPosition", new Point(180, 60));

Expand All @@ -92,6 +117,7 @@ protected override void Initialize() {
private void LoadTextures() {
_textureWatch = ContentsManager.GetTexture(@"textures\605021.png");
_textureWatchActive = ContentsManager.GetTexture(@"textures\605019.png");
_textureClockIcon = ContentsManager.GetTexture(@"textures\clock-icon.png");
}

protected override async Task LoadAsync() {
Expand All @@ -102,11 +128,66 @@ protected override async Task LoadAsync() {
}

protected override void OnModuleLoaded(EventArgs e) {
_eventsTab = GameService.Overlay.BlishHudWindow.AddTab(Resources.Events_and_Metas, this.ContentsManager.GetTexture(@"textures\1466345.png"), _tabPanel);
_tabPanel = BuildSettingPanel(GameService.Overlay.BlishHudWindow.ContentRegion);

UpdateCornerIconState();

GameService.Overlay.BlishHudWindow.AddTab(
Resources.Events_and_Metas,
_textureWatch,
_tabPanel
);

base.OnModuleLoaded(e);
}

private void UpdateCornerIconState() {
if (ShowCornerIcon && _eventsCornerIcon == null) {
_eventsCornerIcon = new CornerIcon() {
Icon = _textureWatch,
BasicTooltipText = $"Events",
Priority = 10
};

_eventsCornerIcon.Click += delegate {
ShowUpcomingEventNotifications();
};

_eventsContextMenu = new ContextMenuStrip();
_eventsCornerIcon.Menu = _eventsContextMenu;
_eventsContextMenu.Shown += delegate {
UpdateContextMenu();
};
} else if (!ShowCornerIcon && _eventsCornerIcon != null) {
_eventsCornerIcon.Dispose();
_eventsCornerIcon = null;
_eventsContextMenu?.Dispose();
_eventsContextMenu = null;
}
}

private void ShowUpcomingEventNotifications() {
if (Meta.Events == null) return;

EventNotification.ClearAll();

var upcomingWatched = Meta.Events
.Where(e => e.IsWatched && e.LastFiredAlertThreshold.HasValue && (e.NextTime - DateTime.Now).TotalMinutes > 0)
.OrderBy(e => e.NextTime)
.ToList();

foreach (var e in upcomingWatched) {
double timeUntil = (e.NextTime - DateTime.Now).TotalMinutes;
EventNotification.ShowNotification(
Resources.ResourceManager.GetString(e.Name) ?? e.Name,
e.Texture,
string.Format(Resources.Starts_in__0_, timeUntil.Minutes().Humanize()),
NotificationDuration,
e.Waypoint
);
}
}

public override IView GetSettingsView() {
return new BasicSettingsView();
}
Expand All @@ -121,6 +202,13 @@ internal void ShowSetNotificationPositions() {
choseLocation.Size = GameService.Graphics.SpriteScreen.ContentRegion.Size;
}

public string GetEventCustomTime(string eventName) {
if (_watchCollection.TryGetSetting(@"customTime:" + eventName, out var setting)) {
return ((SettingEntry<string>)setting).Value;
}
return "";
}

private Panel BuildSettingPanel(Rectangle panelBounds) {
var etPanel = new Panel() {
CanScroll = false,
Expand Down Expand Up @@ -186,6 +274,7 @@ private Panel BuildSettingPanel(Rectangle panelBounds) {

foreach (var meta in Meta.Events) {
var setting = _watchCollection.DefineSetting(@"watchEvent:" + meta.Name, true);
var customTimeSetting = _watchCollection.DefineSetting(@"customTime:" + meta.Name, "");

meta.IsWatched = setting.Value;

Expand All @@ -203,6 +292,21 @@ private Panel BuildSettingPanel(Rectangle panelBounds) {
es2.Icon = meta.Texture;
}

string defaultHint = meta.Reminder.HasValue ? meta.Reminder.Value.ToString() : NotificationPreTime;

var customTimeTextBox = new TextBox() {
Parent = es2,
Location = new Point(230, 15),
Text = customTimeSetting.Value,
BasicTooltipText = "Custom Pre-Time (min) for this event. E.g. '10, 5'",
Width = 60,
PlaceholderText = defaultHint
};

customTimeTextBox.TextChanged += delegate {
customTimeSetting.Value = customTimeTextBox.Text;
};

var nextTimeLabel = new Label() {
Size = new Point(65, es2.ContentRegion.Height),
Text = meta.NextTime.ToShortTimeString(),
Expand Down Expand Up @@ -395,15 +499,52 @@ private void SortEventPanel(string ddSortMethodValue, ref FlowPanel eventPanel)
protected override void Update(GameTime gameTime) {
_elapsedSeconds += gameTime.ElapsedGameTime.TotalSeconds;

UpdateCornerIconState();

if (_elapsedSeconds > TIMER_RECALC_RATE) {
Meta.UpdateEventSchedules();
UpdateContextMenu();
_elapsedSeconds = 0;
}
}

private void UpdateContextMenu() {
if (_eventsContextMenu == null || Meta.Events == null) return;

foreach (var child in _eventsContextMenu.Children.ToList()) {
child.Dispose();
}

var upcomingWatched = Meta.Events
.Where(e => e.IsWatched && e.LastFiredAlertThreshold.HasValue && (e.NextTime - DateTime.Now).TotalMinutes > 0)
.OrderBy(e => e.NextTime)
.ToList();

if (!upcomingWatched.Any()) {
_eventsContextMenu.AddMenuItem("No upcoming watched events");
return;
}

foreach (var e in upcomingWatched) {
double timeUntil = (e.NextTime - DateTime.Now).TotalMinutes;
string timeStr = timeUntil > 0 ? timeUntil.Minutes().Humanize() : "Now";
string name = Resources.ResourceManager.GetString(e.Name) ?? e.Name;

var menuItem = _eventsContextMenu.AddMenuItem($"{name} (in {timeStr})");
if (e.Texture != null && e.Texture.HasTexture) {
// ContextMenuItem might not support icon natively like this in old Blish HUD, but usually it's possible.
// If it doesn't, this line might error, so I'll leave out the icon on the context menu to be safe.
}
}
}

protected override void Unload() {
ModuleInstance = null;

if (_eventsCornerIcon != null) {
_eventsCornerIcon.Dispose();
}

GameService.Overlay.UserLocaleChanged -= ChangeLocalization;
GameService.Overlay.BlishHudWindow.RemoveTab(_eventsTab);
}
Expand Down
Loading