mirror of
https://github.com/cyanfish/naps2.git
synced 2024-09-11 07:15:31 +03:00
Starting in macOS 14 there is a new clipsToBounds property that defaults to false, which is a behavior change. This causes incompatibilities with anything that uses ClipRectangle directly or indirectly. https://developer.apple.com/documentation/macos-release-notes/appkit-release-notes-for-macos-14#NSView #227
147 lines
5.0 KiB
C#
147 lines
5.0 KiB
C#
using System.Threading;
|
|
using Eto.Drawing;
|
|
using Eto.Forms;
|
|
using NAPS2.EtoForms.Layout;
|
|
|
|
namespace NAPS2.EtoForms.Notifications;
|
|
|
|
public abstract class NotificationView : IDisposable
|
|
{
|
|
private const int BORDER_RADIUS = 7;
|
|
private const int CLOSE_BUTTON_SIZE = 18;
|
|
|
|
protected const int HIDE_LONG = 60 * 1000;
|
|
protected const int HIDE_SHORT = 5 * 1000;
|
|
|
|
protected NotificationView(NotificationModel model)
|
|
{
|
|
Model = model;
|
|
}
|
|
|
|
public NotificationModel Model { get; }
|
|
|
|
protected int HideTimeout { get; set; }
|
|
|
|
protected bool ShowClose { get; set; } = true;
|
|
|
|
public NotificationManager? Manager { get; set; }
|
|
|
|
protected abstract LayoutElement PrimaryContent { get; }
|
|
|
|
protected abstract LayoutElement SecondaryContent { get; }
|
|
|
|
protected Color BackgroundColor => Manager!.ColorScheme.NotificationBackgroundColor;
|
|
|
|
protected Color BorderColor => Manager!.ColorScheme.NotificationBorderColor;
|
|
|
|
public LayoutElement CreateContent()
|
|
{
|
|
BeforeCreateContent();
|
|
var drawable = new Drawable();
|
|
drawable.Paint += DrawableOnPaint;
|
|
var closeButton = new CloseButton(Manager!.ColorScheme);
|
|
closeButton.Click += (_, _) => Manager!.Hide(Model);
|
|
drawable.MouseUp += (_, _) => NotificationClicked();
|
|
drawable.Load += (_, _) => SetUpHideTimeout(drawable);
|
|
return L.Row(
|
|
C.Filler(),
|
|
L.Overlay(
|
|
drawable.MinWidth(120),
|
|
L.Column(
|
|
L.Row(
|
|
PrimaryContent,
|
|
ShowClose ? C.Spacer().Width(CLOSE_BUTTON_SIZE) : C.None()),
|
|
SecondaryContent
|
|
).Padding(10, 8, 10, 8),
|
|
ShowClose
|
|
? L.Column(
|
|
L.Row(
|
|
C.Filler(),
|
|
closeButton.Size(CLOSE_BUTTON_SIZE, CLOSE_BUTTON_SIZE)
|
|
),
|
|
C.Filler()
|
|
).Padding(5, 5, 5, 5)
|
|
: C.None()
|
|
)
|
|
);
|
|
}
|
|
|
|
private void SetUpHideTimeout(Control control)
|
|
{
|
|
Timer CreateTimer()
|
|
{
|
|
return new Timer(_ => Manager!.Hide(Model), null, HideTimeout, -1);
|
|
}
|
|
|
|
if (HideTimeout > 0)
|
|
{
|
|
// Don't start the timer until the user is interacting with the window
|
|
void StartTimer(object? sender, EventArgs e)
|
|
{
|
|
Manager!.TimersStarting -= StartTimer;
|
|
control.ParentWindow.MouseMove -= StartTimer;
|
|
var timer = CreateTimer();
|
|
control.MouseEnter += (_, _) => timer.Dispose();
|
|
control.MouseLeave += (_, _) => timer = CreateTimer();
|
|
}
|
|
|
|
Manager!.TimersStarting += StartTimer;
|
|
}
|
|
}
|
|
|
|
protected virtual void BeforeCreateContent()
|
|
{
|
|
}
|
|
|
|
protected virtual void NotificationClicked()
|
|
{
|
|
}
|
|
|
|
private void DrawableOnPaint(object? sender, PaintEventArgs e)
|
|
{
|
|
var drawable = (Drawable) sender!;
|
|
var w = drawable.Width;
|
|
var h = drawable.Height;
|
|
e.Graphics.FillRectangle(BackgroundColor, 0, 0, w, h);
|
|
e.Graphics.DrawRectangle(BorderColor, 0, 0, w - 1, h - 1);
|
|
}
|
|
|
|
private void DrawWithRoundedCorners(Drawable drawable, PaintEventArgs e)
|
|
{
|
|
// TODO: We're not using this as the few pixels on the edges aren't transparent, which is a problem if there's
|
|
// an image underneath. Not sure if there's a way to make that work but I don't care enough about rounded
|
|
// corners at the moment.
|
|
var w = drawable.Width;
|
|
var h = drawable.Height;
|
|
var r = BORDER_RADIUS;
|
|
var d = r * 2;
|
|
var q = r / 2;
|
|
e.Graphics.FillRectangle(Manager!.ColorScheme.BackgroundColor, 0, 0, w, h);
|
|
// Corners
|
|
e.Graphics.FillEllipse(BackgroundColor, -1, -1, d, d);
|
|
e.Graphics.FillEllipse(BackgroundColor, w - d, -1, d, d);
|
|
e.Graphics.FillEllipse(BackgroundColor, -1, h - d, d, d);
|
|
e.Graphics.FillEllipse(BackgroundColor, w - d, h - d, d, d);
|
|
// Corner borders
|
|
e.Graphics.DrawEllipse(BorderColor, -1, -1, d, d);
|
|
e.Graphics.DrawEllipse(BorderColor, w - d, -1, d, d);
|
|
e.Graphics.DrawEllipse(BorderColor, -1, h - d, d, d);
|
|
e.Graphics.DrawEllipse(BorderColor, w - d, h - d, d, d);
|
|
// Middle
|
|
e.Graphics.FillRectangle(BackgroundColor, r, r, w - d, h - d);
|
|
// Sides
|
|
e.Graphics.FillRectangle(BackgroundColor, 0, r, r, h - d);
|
|
e.Graphics.FillRectangle(BackgroundColor, r, 0, w - d, r);
|
|
e.Graphics.FillRectangle(BackgroundColor, w - r, r, r, h - d);
|
|
e.Graphics.FillRectangle(BackgroundColor, r, h - r, w - d, r);
|
|
// Side borders
|
|
e.Graphics.DrawLine(BorderColor, 0, q, 0, h - q);
|
|
e.Graphics.DrawLine(BorderColor, q, 0, w - q, 0);
|
|
e.Graphics.DrawLine(BorderColor, w - 1, q, w - 1, h - q);
|
|
e.Graphics.DrawLine(BorderColor, q, h - 1, w - q, h - 1);
|
|
}
|
|
|
|
public virtual void Dispose()
|
|
{
|
|
}
|
|
} |