mirror of
https://github.com/9ParsonsB/Pulsar.git
synced 2025-04-05 17:39:39 -04:00
Polishing a few rough edges: * Enable scrolling on the Plugin List view. It only fit 6 or 7. I have 13. * I fiddled a bit with column auto-sizing (left it commented out, see comment). * A whole bunch of tweaks to the settings view: * first row of controls was cut off at the top (under the window title bar) * fixing that revealed uneven spacing between columns * action buttons were teensy tiny and unreadable * settings view columns were too narrow (200 px). * added some spacing to help with readability * settings windows now start in center of current screen rather than some random place.
322 lines
12 KiB
C#
322 lines
12 KiB
C#
using Observatory.Framework;
|
||
using Observatory.Framework.Interfaces;
|
||
using Observatory.PluginManagement;
|
||
using Observatory.Utils;
|
||
using System.Diagnostics;
|
||
using System.Runtime.InteropServices;
|
||
using System.Text;
|
||
using System.Windows.Forms;
|
||
|
||
namespace Observatory.UI
|
||
{
|
||
public partial class CoreForm : Form
|
||
{
|
||
private readonly Dictionary<object, Panel> uiPanels;
|
||
|
||
[DllImport("user32.dll")]
|
||
private static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);
|
||
private const int WM_SETREDRAW = 11;
|
||
private static void SuspendDrawing(Control control)
|
||
{
|
||
SendMessage(control.Handle, WM_SETREDRAW, false, 0);
|
||
}
|
||
|
||
private static void ResumeDrawing(Control control)
|
||
{
|
||
SendMessage(control.Handle, WM_SETREDRAW, true, 0);
|
||
control.Refresh();
|
||
}
|
||
|
||
public CoreForm()
|
||
{
|
||
DoubleBuffered = true;
|
||
InitializeComponent();
|
||
|
||
PopulateDropdownOptions();
|
||
PopulateNativeSettings();
|
||
|
||
ColourListHeader(ref PluginList, Color.DarkSlateGray, Color.LightGray);
|
||
PopulatePluginList();
|
||
FitColumns();
|
||
string version = System.Reflection.Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "0";
|
||
Text += $" - v{version}";
|
||
CoreMenu.SizeChanged += CoreMenu_SizeChanged;
|
||
uiPanels = new()
|
||
{
|
||
{ coreToolStripMenuItem, CorePanel }
|
||
};
|
||
|
||
|
||
pluginList = new Dictionary<string, ToolStripMenuItem>();
|
||
CreatePluginTabs();
|
||
DisableOverriddenNotification();
|
||
CoreMenu.ItemClicked += CoreMenu_ItemClicked;
|
||
|
||
PreCollapsePanels();
|
||
|
||
ThemeManager.GetInstance.RegisterControl(this);
|
||
}
|
||
|
||
private void PreCollapsePanels()
|
||
{
|
||
AdjustPanelsBelow(VoiceSettingsPanel, AdjustmentDirection.Up);
|
||
AdjustPanelsBelow(PopupSettingsPanel, AdjustmentDirection.Up);
|
||
}
|
||
|
||
private void CoreMenu_SizeChanged(object? sender, EventArgs e)
|
||
{
|
||
CorePanel.Location = new Point(12 + CoreMenu.Width, 12);
|
||
CorePanel.Width = Width - CoreMenu.Width - 40;
|
||
|
||
}
|
||
|
||
private readonly Dictionary<string, ToolStripMenuItem> pluginList;
|
||
|
||
private void ToggleMonitorButton_Click(object sender, EventArgs e)
|
||
{
|
||
if ((LogMonitor.GetInstance.CurrentState & Framework.LogMonitorState.Realtime) == Framework.LogMonitorState.Realtime)
|
||
{
|
||
LogMonitor.GetInstance.Stop();
|
||
ToggleMonitorButton.Text = "Start Monitor";
|
||
}
|
||
else
|
||
{
|
||
LogMonitor.GetInstance.Start();
|
||
ToggleMonitorButton.Text = "Stop Monitor";
|
||
}
|
||
}
|
||
|
||
private void ResizePanels(Point location, int widthChange)
|
||
{
|
||
|
||
CorePanel.Location = location;
|
||
CorePanel.Width += widthChange;
|
||
foreach (var panel in uiPanels)
|
||
{
|
||
if (Controls.Contains(panel.Value))
|
||
{
|
||
panel.Value.Location = CorePanel.Location;
|
||
panel.Value.Size = CorePanel.Size;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
private void CoreMenu_ItemClicked(object? _, ToolStripItemClickedEventArgs e)
|
||
{
|
||
SuspendDrawing(this);
|
||
if (e.ClickedItem.Text == "<")
|
||
{
|
||
foreach (KeyValuePair<string, ToolStripMenuItem> menuItem in pluginList)
|
||
{
|
||
if (menuItem.Value.Text == "<")
|
||
menuItem.Value.Text = ">";
|
||
else
|
||
menuItem.Value.Text = menuItem.Key[..1];
|
||
}
|
||
CoreMenu.Width = 40;
|
||
ResizePanels(new Point(43, 12), 0);
|
||
}
|
||
else if (e.ClickedItem.Text == ">")
|
||
{
|
||
foreach (KeyValuePair<string, ToolStripMenuItem> menuItem in pluginList)
|
||
{
|
||
if (menuItem.Value.Text == ">")
|
||
menuItem.Value.Text = "<";
|
||
else
|
||
menuItem.Value.Text = menuItem.Key;
|
||
}
|
||
CoreMenu.Width = GetExpandedMenuWidth();
|
||
ResizePanels(new Point(CoreMenu.Width + 3, 12), 0);
|
||
}
|
||
else
|
||
{
|
||
foreach (var panel in uiPanels.Where(p => p.Key != e.ClickedItem))
|
||
{
|
||
panel.Value.Visible = false;
|
||
}
|
||
|
||
if (!Controls.Contains(uiPanels[e.ClickedItem]))
|
||
{
|
||
uiPanels[e.ClickedItem].Location = CorePanel.Location;
|
||
uiPanels[e.ClickedItem].Size = CorePanel.Size;
|
||
uiPanels[e.ClickedItem].BackColor = CorePanel.BackColor;
|
||
uiPanels[e.ClickedItem].Parent = CorePanel.Parent;
|
||
Controls.Add(uiPanels[e.ClickedItem]);
|
||
}
|
||
uiPanels[e.ClickedItem].Visible = true;
|
||
|
||
SetClickedItem(e.ClickedItem);
|
||
}
|
||
ResumeDrawing(this);
|
||
}
|
||
|
||
private void SetClickedItem(ToolStripItem item)
|
||
{
|
||
foreach (ToolStripItem menuItem in CoreMenu.Items)
|
||
{
|
||
bool bold = menuItem == item;
|
||
menuItem.Font = new Font(menuItem.Font, bold ? FontStyle.Bold : FontStyle.Regular);
|
||
}
|
||
}
|
||
|
||
private static void ColourListHeader(ref ListView list, Color backColor, Color foreColor)
|
||
{
|
||
list.OwnerDraw = true;
|
||
|
||
list.DrawColumnHeader +=
|
||
new DrawListViewColumnHeaderEventHandler
|
||
(
|
||
(sender, e) => HeaderDraw(sender, e, backColor, foreColor)
|
||
);
|
||
list.DrawItem += new DrawListViewItemEventHandler(BodyDraw);
|
||
}
|
||
|
||
private static void HeaderDraw(object? _, DrawListViewColumnHeaderEventArgs e, Color backColor, Color foreColor)
|
||
{
|
||
using (SolidBrush backBrush = new(backColor))
|
||
{
|
||
e.Graphics.FillRectangle(backBrush, e.Bounds);
|
||
}
|
||
|
||
using (Pen borderBrush = new(Color.Black))
|
||
{
|
||
e.Graphics.DrawLine(borderBrush, e.Bounds.Left, e.Bounds.Top, e.Bounds.Left, e.Bounds.Bottom);
|
||
e.Graphics.DrawLine(borderBrush, e.Bounds.Right, e.Bounds.Top, e.Bounds.Right, e.Bounds.Bottom);
|
||
}
|
||
|
||
if (e.Font != null && e.Header != null)
|
||
using (SolidBrush foreBrush = new(foreColor))
|
||
{
|
||
var format = new StringFormat
|
||
{
|
||
Alignment = (StringAlignment)e.Header.TextAlign,
|
||
LineAlignment = StringAlignment.Center
|
||
};
|
||
|
||
var paddedBounds = new Rectangle(e.Bounds.X + 2, e.Bounds.Y + 2, e.Bounds.Width - 4, e.Bounds.Height - 4);
|
||
|
||
e.Graphics.DrawString(e.Header?.Text, e.Font, foreBrush, paddedBounds, format);
|
||
}
|
||
}
|
||
|
||
private static void BodyDraw(object? _, DrawListViewItemEventArgs e)
|
||
{
|
||
e.DrawDefault = true;
|
||
}
|
||
|
||
private void PluginList_Resize(object sender, EventArgs e)
|
||
{
|
||
FitColumns();
|
||
}
|
||
|
||
private void FitColumns()
|
||
{
|
||
// This sizes to fit the column width to the text. However, when the listview is resized (by
|
||
// expanding setting sections below the list), it causes flashing/jank. Visually, it looks cleaner
|
||
// (because the default column sizes are too small) and helps avoid horizontal scrollbar.
|
||
//foreach (ColumnHeader col in PluginList.Columns)
|
||
// col.Width = -2;
|
||
|
||
int totalWidth = 0;
|
||
foreach (ColumnHeader col in PluginList.Columns)
|
||
totalWidth += col.Width;
|
||
|
||
PluginList.Columns[3].Width += PluginList.Width - totalWidth;
|
||
}
|
||
|
||
private void ReadAllButton_Click(object sender, EventArgs e)
|
||
{
|
||
var readAllDialogue = new ReadAllForm();
|
||
ThemeManager.GetInstance.RegisterControl(readAllDialogue);
|
||
readAllDialogue.StartPosition = FormStartPosition.Manual;
|
||
readAllDialogue.Location = Point.Add(Location, new Size(100, 100));
|
||
readAllDialogue.ShowDialog();
|
||
}
|
||
|
||
private void PopupNotificationLabel_Click(object _, EventArgs e)
|
||
{
|
||
CorePanel.SuspendLayout();
|
||
if (PopupNotificationLabel.Text[0] == '❯')
|
||
{
|
||
PopupNotificationLabel.Text = PopupNotificationLabel.Text.Replace('❯', '⌵');
|
||
PopupSettingsPanel.Visible = true;
|
||
AdjustPanelsBelow(PopupSettingsPanel, AdjustmentDirection.Down);
|
||
}
|
||
else
|
||
{
|
||
PopupNotificationLabel.Text = PopupNotificationLabel.Text.Replace('⌵', '❯');
|
||
PopupSettingsPanel.Visible = false;
|
||
AdjustPanelsBelow(PopupSettingsPanel, AdjustmentDirection.Up);
|
||
}
|
||
CorePanel.ResumeLayout();
|
||
}
|
||
|
||
private void VoiceNotificationLabel_Click(object sender, EventArgs e)
|
||
{
|
||
CorePanel.SuspendLayout();
|
||
if (VoiceNotificationLabel.Text[0] == '❯')
|
||
{
|
||
VoiceNotificationLabel.Text = VoiceNotificationLabel.Text.Replace('❯', '⌵');
|
||
VoiceSettingsPanel.Visible = true;
|
||
AdjustPanelsBelow(VoiceSettingsPanel, AdjustmentDirection.Down);
|
||
}
|
||
else
|
||
{
|
||
VoiceNotificationLabel.Text = VoiceNotificationLabel.Text.Replace('⌵', '❯');
|
||
VoiceSettingsPanel.Visible = false;
|
||
AdjustPanelsBelow(VoiceSettingsPanel, AdjustmentDirection.Up);
|
||
}
|
||
CorePanel.ResumeLayout();
|
||
}
|
||
|
||
private void AdjustPanelsBelow(Control toggledControl, AdjustmentDirection adjustmentDirection)
|
||
{
|
||
var distance = adjustmentDirection == AdjustmentDirection.Down ? toggledControl.Height : -toggledControl.Height;
|
||
foreach (Control control in CorePanel.Controls)
|
||
{
|
||
var loc = control.Location;
|
||
if (loc.Y >= toggledControl.Location.Y && control != toggledControl)
|
||
{
|
||
loc.Y = control.Location.Y + distance;
|
||
control.Location = loc;
|
||
}
|
||
}
|
||
}
|
||
|
||
internal enum AdjustmentDirection
|
||
{
|
||
Up, Down
|
||
}
|
||
|
||
private Observatory.NativeNotification.NativePopup? nativePopup;
|
||
|
||
private void TestButton_Click(object sender, EventArgs e)
|
||
{
|
||
NotificationArgs args = new()
|
||
{
|
||
Title = "Test Notification",
|
||
Detail = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec at elit maximus, ornare dui nec, accumsan velit. Vestibulum fringilla elit."
|
||
};
|
||
|
||
nativePopup ??= new Observatory.NativeNotification.NativePopup();
|
||
|
||
nativePopup.InvokeNativeNotification(args);
|
||
}
|
||
|
||
private void GithubLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||
{
|
||
OpenURL("https://github.com/Xjph/ObservatoryCore");
|
||
}
|
||
|
||
private void DonateLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||
{
|
||
OpenURL("https://www.paypal.com/paypalme/eliteobservatory");
|
||
}
|
||
|
||
private void OpenURL(string url)
|
||
{
|
||
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
|
||
}
|
||
}
|
||
} |