1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-08-17 00:31:42 +02:00
Files
Configuration
Core
Bridge
Controls
Handling
Management
Notification
Example
Screenshot
FormNotificationBase.Designer.cs
FormNotificationBase.cs
FormNotificationMain.Designer.cs
FormNotificationMain.cs
FormNotificationTweet.Designer.cs
FormNotificationTweet.cs
SoundNotification.cs
TweetNotification.cs
Other
Utils
FormBrowser.Designer.cs
FormBrowser.cs
FormBrowser.resx
FormManager.cs
TweetDeckBrowser.cs
Data
Plugins
Properties
Resources
Updates
bld
lib
subprocess
video
.gitattributes
.gitignore
LICENSE.md
Program.cs
README.md
Reporter.cs
TweetDuck.csproj
TweetDuck.sln
TweetDuck.sln.DotSettings
packages.config
TweetDuck/Core/Notification/FormNotificationMain.cs
2018-08-10 03:18:26 +02:00

277 lines
9.8 KiB
C#

using CefSharp;
using System;
using System.Drawing;
using System.Windows.Forms;
using TweetDuck.Core.Bridge;
using TweetDuck.Core.Controls;
using TweetDuck.Core.Handling;
using TweetDuck.Core.Utils;
using TweetDuck.Data;
using TweetDuck.Plugins;
using TweetDuck.Plugins.Enums;
using TweetDuck.Resources;
namespace TweetDuck.Core.Notification{
abstract partial class FormNotificationMain : FormNotificationBase{
private readonly PluginManager plugins;
private readonly int timerBarHeight;
protected int timeLeft, totalTime;
protected bool pausedDuringNotification;
private readonly NativeMethods.HookProc mouseHookDelegate;
private IntPtr mouseHook;
private bool blockXButtonUp;
private bool? prevDisplayTimer;
private int? prevFontSize;
public virtual bool RequiresResize{
get{
return !prevDisplayTimer.HasValue || !prevFontSize.HasValue || prevDisplayTimer != Config.DisplayNotificationTimer || prevFontSize != FontSizeLevel;
}
set{
if (value){
prevDisplayTimer = null;
prevFontSize = null;
}
else{
prevDisplayTimer = Config.DisplayNotificationTimer;
prevFontSize = FontSizeLevel;
}
}
}
private int BaseClientWidth{
get{
switch(Config.NotificationSize){
default:
return BrowserUtils.Scale(284, SizeScale*(1.0+0.05*FontSizeLevel));
case TweetNotification.Size.Custom:
return Config.CustomNotificationSize.Width;
}
}
}
private int BaseClientHeight{
get{
switch(Config.NotificationSize){
default:
return BrowserUtils.Scale(122, SizeScale*(1.0+0.08*FontSizeLevel));
case TweetNotification.Size.Custom:
return Config.CustomNotificationSize.Height;
}
}
}
protected virtual string BodyClasses => IsCursorOverBrowser ? "td-notification td-hover" : "td-notification";
public Size BrowserSize => Config.DisplayNotificationTimer ? new Size(ClientSize.Width, ClientSize.Height-timerBarHeight) : ClientSize;
protected FormNotificationMain(FormBrowser owner, PluginManager pluginManager, bool enableContextMenu) : base(owner, enableContextMenu){
InitializeComponent();
this.plugins = pluginManager;
this.timerBarHeight = BrowserUtils.Scale(4, DpiScale);
browser.KeyboardHandler = new KeyboardHandlerNotification(this);
browser.RegisterAsyncJsObject("$TD", new TweetDeckBridge.Notification(owner, this));
browser.LoadingStateChanged += Browser_LoadingStateChanged;
browser.FrameLoadEnd += Browser_FrameLoadEnd;
plugins.Register(browser, PluginEnvironment.Notification, this);
mouseHookDelegate = MouseHookProc;
Disposed += (sender, args) => StopMouseHook(true);
}
// mouse wheel hook
private void StartMouseHook(){
if (mouseHook == IntPtr.Zero){
mouseHook = NativeMethods.SetWindowsHookEx(NativeMethods.WM_MOUSE_LL, mouseHookDelegate, IntPtr.Zero, 0);
}
}
private void StopMouseHook(bool force){
if (mouseHook != IntPtr.Zero && (force || !blockXButtonUp)){
NativeMethods.UnhookWindowsHookEx(mouseHook);
mouseHook = IntPtr.Zero;
blockXButtonUp = false;
}
}
private IntPtr MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam){
if (nCode == 0){
int eventType = wParam.ToInt32();
if (eventType == NativeMethods.WM_MOUSEWHEEL && IsCursorOverBrowser){
browser.SendMouseWheelEvent(0, 0, 0, BrowserUtils.Scale(NativeMethods.GetMouseHookData(lParam), Config.NotificationScrollSpeed*0.01), CefEventFlags.None);
return NativeMethods.HOOK_HANDLED;
}
else if (eventType == NativeMethods.WM_XBUTTONDOWN && DesktopBounds.Contains(Cursor.Position)){
int extraButton = NativeMethods.GetMouseHookData(lParam);
if (extraButton == 2){ // forward button
this.InvokeAsyncSafe(FinishCurrentNotification);
}
else if (extraButton == 1){ // back button
this.InvokeAsyncSafe(Close);
}
blockXButtonUp = true;
this.InvokeAsyncSafe(AnalyticsFile.NotificationExtraMouseButtons.Trigger);
return NativeMethods.HOOK_HANDLED;
}
else if (eventType == NativeMethods.WM_XBUTTONUP && blockXButtonUp){
blockXButtonUp = false;
if (!Visible){
StopMouseHook(false);
}
return NativeMethods.HOOK_HANDLED;
}
}
return NativeMethods.CallNextHookEx(mouseHook, nCode, wParam, lParam);
}
// event handlers
private void FormNotification_FormClosing(object sender, FormClosingEventArgs e){
if (e.CloseReason == CloseReason.UserClosing){
HideNotification();
e.Cancel = true;
}
}
private void Browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e){
if (!e.IsLoading && browser.Address != "about:blank"){
this.InvokeSafe(() => {
Visible = true; // ensures repaint before moving the window to a visible location
timerDisplayDelay.Start();
});
}
}
private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
IFrame frame = e.Frame;
if (frame.IsMain && browser.Address != "about:blank"){
frame.ExecuteJavaScriptAsync(PropertyBridge.GenerateScript(PropertyBridge.Environment.Notification));
ScriptLoader.ExecuteFile(frame, "notification.js", this);
}
}
private void timerDisplayDelay_Tick(object sender, EventArgs e){
OnNotificationReady();
timerDisplayDelay.Stop();
}
private void timerHideProgress_Tick(object sender, EventArgs e){
if (Bounds.Contains(Cursor.Position) || FreezeTimer || ContextMenuOpen){
return;
}
timeLeft -= timerProgress.Interval;
int value = BrowserUtils.Scale(progressBarTimer.Maximum+25, (totalTime-timeLeft)/(double)totalTime);
progressBarTimer.SetValueInstant(Config.NotificationTimerCountDown ? progressBarTimer.Maximum-value : value);
if (timeLeft <= 0){
FinishCurrentNotification();
}
}
// notification methods
public virtual void ShowNotification(TweetNotification notification){
LoadTweet(notification);
}
public override void HideNotification(){
base.HideNotification();
progressBarTimer.Value = Config.NotificationTimerCountDown ? progressBarTimer.Maximum : progressBarTimer.Minimum;
timerProgress.Stop();
totalTime = 0;
StopMouseHook(false);
}
public override void FinishCurrentNotification(){
timerProgress.Stop();
}
public override void PauseNotification(){
if (!IsPaused){
pausedDuringNotification = IsNotificationVisible;
timerProgress.Stop();
StopMouseHook(true);
}
base.PauseNotification();
}
public override void ResumeNotification(){
bool wasPaused = IsPaused;
base.ResumeNotification();
if (wasPaused && !IsPaused && pausedDuringNotification){
OnNotificationReady();
}
}
protected override string GetTweetHTML(TweetNotification tweet){
string html = tweet.GenerateHtml(BodyClasses, this);
foreach(InjectedHTML injection in plugins.NotificationInjections){
html = injection.InjectInto(html);
}
return html;
}
protected override void LoadTweet(TweetNotification tweet){
timerProgress.Stop();
totalTime = timeLeft = tweet.GetDisplayDuration(Config.NotificationDurationValue);
progressBarTimer.Value = Config.NotificationTimerCountDown ? progressBarTimer.Maximum : progressBarTimer.Minimum;
base.LoadTweet(tweet);
}
protected override void SetNotificationSize(int width, int height){
if (Config.DisplayNotificationTimer){
ClientSize = new Size(width, height+timerBarHeight);
progressBarTimer.Visible = true;
}
else{
ClientSize = new Size(width, height);
progressBarTimer.Visible = false;
}
browser.ClientSize = new Size(width, height);
}
protected void PrepareAndDisplayWindow(){
if (RequiresResize){
RequiresResize = false;
SetNotificationSize(BaseClientWidth, BaseClientHeight);
}
MoveToVisibleLocation();
StartMouseHook();
}
protected virtual void OnNotificationReady(){
PrepareAndDisplayWindow();
timerProgress.Start();
}
}
}