1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-04-09 06:15:49 +02:00

Add a setting for non-intrusive popups to avoid accidental clicks

This commit is contained in:
chylex 2017-03-21 00:11:13 +01:00
parent 5aaae51be1
commit 96146e3dc8
7 changed files with 159 additions and 44 deletions

View File

@ -14,13 +14,14 @@ namespace TweetDck.Configuration{
sealed class UserConfig{
private static readonly IFormatter Formatter = new BinaryFormatter();
private const int CurrentFileVersion = 6;
private const int CurrentFileVersion = 7;
// START OF CONFIGURATION
public WindowState BrowserWindow { get; set; }
public bool DisplayNotificationTimer { get; set; }
public bool NotificationTimerCountDown { get; set; }
public bool NotificationNonIntrusiveMode { get; set; }
public TweetNotification.Position NotificationPosition { get; set; }
public Point CustomNotificationPosition { get; set; }
@ -112,6 +113,7 @@ private UserConfig(string file){
BrowserWindow = new WindowState();
DisplayNotificationTimer = true;
NotificationNonIntrusiveMode = true;
NotificationPosition = TweetNotification.Position.TopRight;
CustomNotificationPosition = ControlExtensions.InvisibleLocation;
NotificationEdgeDistance = 8;
@ -168,6 +170,11 @@ private void UpgradeFile(){
++fileVersion;
}
if (fileVersion == 6){
NotificationNonIntrusiveMode = true;
++fileVersion;
}
// update the version
fileVersion = CurrentFileVersion;
Save();

View File

@ -10,6 +10,46 @@
namespace TweetDck.Core.Notification{
partial class FormNotificationBase : Form{
protected Point PrimaryLocation{
get{
UserConfig config = Program.UserConfig;
Screen screen;
if (config.NotificationDisplay > 0 && config.NotificationDisplay <= Screen.AllScreens.Length){
screen = Screen.AllScreens[config.NotificationDisplay-1];
}
else{
screen = Screen.FromControl(owner);
}
int edgeDist = config.NotificationEdgeDistance;
switch(config.NotificationPosition){
case TweetNotification.Position.TopLeft:
return new Point(screen.WorkingArea.X+edgeDist, screen.WorkingArea.Y+edgeDist);
case TweetNotification.Position.TopRight:
return new Point(screen.WorkingArea.X+screen.WorkingArea.Width-edgeDist-Width, screen.WorkingArea.Y+edgeDist);
case TweetNotification.Position.BottomLeft:
return new Point(screen.WorkingArea.X+edgeDist, screen.WorkingArea.Y+screen.WorkingArea.Height-edgeDist-Height);
case TweetNotification.Position.BottomRight:
return new Point(screen.WorkingArea.X+screen.WorkingArea.Width-edgeDist-Width, screen.WorkingArea.Y+screen.WorkingArea.Height-edgeDist-Height);
case TweetNotification.Position.Custom:
if (!config.IsCustomNotificationPositionSet){
config.CustomNotificationPosition = new Point(screen.WorkingArea.X+screen.WorkingArea.Width-edgeDist-Width, screen.WorkingArea.Y+edgeDist);
config.Save();
}
return config.CustomNotificationPosition;
}
return Location;
}
}
public bool IsNotificationVisible{
get{
return Location != ControlExtensions.InvisibleLocation;
@ -141,43 +181,8 @@ protected virtual void SetNotificationSize(int width, int height){
}
protected void MoveToVisibleLocation(){
UserConfig config = Program.UserConfig;
Screen screen = Screen.FromControl(owner);
if (config.NotificationDisplay > 0 && config.NotificationDisplay <= Screen.AllScreens.Length){
screen = Screen.AllScreens[config.NotificationDisplay-1];
}
bool needsReactivating = Location == ControlExtensions.InvisibleLocation;
int edgeDist = config.NotificationEdgeDistance;
switch(config.NotificationPosition){
case TweetNotification.Position.TopLeft:
Location = new Point(screen.WorkingArea.X+edgeDist, screen.WorkingArea.Y+edgeDist);
break;
case TweetNotification.Position.TopRight:
Location = new Point(screen.WorkingArea.X+screen.WorkingArea.Width-edgeDist-Width, screen.WorkingArea.Y+edgeDist);
break;
case TweetNotification.Position.BottomLeft:
Location = new Point(screen.WorkingArea.X+edgeDist, screen.WorkingArea.Y+screen.WorkingArea.Height-edgeDist-Height);
break;
case TweetNotification.Position.BottomRight:
Location = new Point(screen.WorkingArea.X+screen.WorkingArea.Width-edgeDist-Width, screen.WorkingArea.Y+screen.WorkingArea.Height-edgeDist-Height);
break;
case TweetNotification.Position.Custom:
if (!config.IsCustomNotificationPositionSet){
config.CustomNotificationPosition = new Point(screen.WorkingArea.X+screen.WorkingArea.Width-edgeDist-Width, screen.WorkingArea.Y+edgeDist);
config.Save();
}
Location = config.CustomNotificationPosition;
break;
}
Location = PrimaryLocation;
if (needsReactivating && flags.HasFlag(NotificationFlags.TopMost)){
NativeMethods.SetFormPos(this, NativeMethods.HWND_TOPMOST, NativeMethods.SWP_NOACTIVATE);

View File

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TweetDck.Core.Notification {
partial class FormNotificationTweet {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
this.components = new System.ComponentModel.Container();
this.timerCursorCheck = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// timerCursorCheck
//
this.timerCursorCheck.Interval = 200;
this.timerCursorCheck.Tick += new System.EventHandler(this.timerCursorCheck_Tick);
//
// FormNotificationTweet
//
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormNotificationTweet_FormClosing);
this.ResumeLayout(true);
}
#endregion
private System.Windows.Forms.Timer timerCursorCheck;
}
}

View File

@ -1,21 +1,31 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using TweetDck.Plugins;
using System.Windows.Forms;
using TweetDck.Core.Utils;
namespace TweetDck.Core.Notification{
sealed class FormNotificationTweet : FormNotificationMain{
sealed partial class FormNotificationTweet : FormNotificationMain{
private const int NonIntrusiveIdleLimit = 30;
private bool IsCursorOverNotificationArea{
get{
return new Rectangle(PrimaryLocation, Size).Contains(Cursor.Position);
}
}
private readonly Queue<TweetNotification> tweetQueue = new Queue<TweetNotification>(4);
public FormNotificationTweet(FormBrowser owner, PluginManager pluginManager, NotificationFlags flags) : base(owner, pluginManager, flags){
InitializeComponent();
Program.UserConfig.MuteToggled += Config_MuteToggled;
Disposed += (sender, args) => Program.UserConfig.MuteToggled -= Config_MuteToggled;
if (Program.UserConfig.MuteNotifications){
PauseNotification();
}
FormClosing += FormNotificationTweet_FormClosing;
}
private void FormNotificationTweet_FormClosing(object sender, FormClosingEventArgs e){
@ -35,6 +45,13 @@ private void Config_MuteToggled(object sender, EventArgs e){
}
}
private void timerCursorCheck_Tick(object sender, EventArgs e){
if (!IsCursorOverNotificationArea){
ResumeNotification();
timerCursorCheck.Stop();
}
}
// notification methods
public override void ShowNotification(TweetNotification notification){
@ -70,7 +87,15 @@ public override void ResumeNotification(){
}
private void LoadNextNotification(){
LoadTweet(tweetQueue.Dequeue());
if (Program.UserConfig.NotificationNonIntrusiveMode && !IsNotificationVisible && IsCursorOverNotificationArea && NativeMethods.GetIdleSeconds() < NonIntrusiveIdleLimit){
if (!timerCursorCheck.Enabled){
PauseNotification();
timerCursorCheck.Start();
}
}
else{
LoadTweet(tweetQueue.Dequeue());
}
}
protected override void UpdateTitle(){

View File

@ -43,6 +43,7 @@ private void InitializeComponent() {
this.labelDurationValue = new System.Windows.Forms.Label();
this.trackBarDuration = new System.Windows.Forms.TrackBar();
this.groupUserInterface = new System.Windows.Forms.GroupBox();
this.checkNonIntrusive = new System.Windows.Forms.CheckBox();
this.checkTimerCountDown = new System.Windows.Forms.CheckBox();
this.checkNotificationTimer = new System.Windows.Forms.CheckBox();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
@ -203,7 +204,7 @@ private void InitializeComponent() {
this.groupNotificationDuration.Controls.Add(this.tableLayoutDurationButtons);
this.groupNotificationDuration.Controls.Add(this.labelDurationValue);
this.groupNotificationDuration.Controls.Add(this.trackBarDuration);
this.groupNotificationDuration.Location = new System.Drawing.Point(9, 83);
this.groupNotificationDuration.Location = new System.Drawing.Point(9, 106);
this.groupNotificationDuration.Name = "groupNotificationDuration";
this.groupNotificationDuration.Size = new System.Drawing.Size(183, 89);
this.groupNotificationDuration.TabIndex = 9;
@ -305,15 +306,29 @@ private void InitializeComponent() {
//
// groupUserInterface
//
this.groupUserInterface.Controls.Add(this.checkNonIntrusive);
this.groupUserInterface.Controls.Add(this.checkTimerCountDown);
this.groupUserInterface.Controls.Add(this.checkNotificationTimer);
this.groupUserInterface.Location = new System.Drawing.Point(9, 9);
this.groupUserInterface.Name = "groupUserInterface";
this.groupUserInterface.Size = new System.Drawing.Size(183, 68);
this.groupUserInterface.Size = new System.Drawing.Size(183, 91);
this.groupUserInterface.TabIndex = 10;
this.groupUserInterface.TabStop = false;
this.groupUserInterface.Text = "General";
//
// checkNonIntrusive
//
this.checkNonIntrusive.AutoSize = true;
this.checkNonIntrusive.Location = new System.Drawing.Point(6, 67);
this.checkNonIntrusive.Name = "checkNonIntrusive";
this.checkNonIntrusive.Size = new System.Drawing.Size(123, 17);
this.checkNonIntrusive.TabIndex = 7;
this.checkNonIntrusive.Text = "Non-Intrusive Popup";
this.toolTip.SetToolTip(this.checkNonIntrusive, "When not idle and the cursor is within the notification window area,\r\nit will be " +
"delayed until the cursor moves away to prevent accidental clicks.");
this.checkNonIntrusive.UseVisualStyleBackColor = true;
this.checkNonIntrusive.CheckedChanged += new System.EventHandler(this.checkNonIntrusive_CheckedChanged);
//
// checkTimerCountDown
//
this.checkTimerCountDown.AutoSize = true;
@ -344,7 +359,7 @@ private void InitializeComponent() {
this.groupCustomSound.Controls.Add(this.btnResetSound);
this.groupCustomSound.Controls.Add(this.btnBrowseSound);
this.groupCustomSound.Controls.Add(this.tbCustomSound);
this.groupCustomSound.Location = new System.Drawing.Point(9, 178);
this.groupCustomSound.Location = new System.Drawing.Point(9, 201);
this.groupCustomSound.Name = "groupCustomSound";
this.groupCustomSound.Size = new System.Drawing.Size(183, 72);
this.groupCustomSound.TabIndex = 11;
@ -437,5 +452,6 @@ private void InitializeComponent() {
private System.Windows.Forms.Button btnResetSound;
private System.Windows.Forms.Button btnBrowseSound;
private System.Windows.Forms.TextBox tbCustomSound;
private System.Windows.Forms.CheckBox checkNonIntrusive;
}
}

View File

@ -55,6 +55,7 @@ public TabSettingsNotifications(FormNotificationMain notification, bool ignoreAu
checkNotificationTimer.Checked = Config.DisplayNotificationTimer;
checkTimerCountDown.Enabled = checkNotificationTimer.Checked;
checkTimerCountDown.Checked = Config.NotificationTimerCountDown;
checkNotificationTimer.Checked = Config.NotificationNonIntrusiveMode;
trackBarEdgeDistance.SetValueSafe(Config.NotificationEdgeDistance);
labelEdgeDistanceValue.Text = trackBarEdgeDistance.Value.ToString(CultureInfo.InvariantCulture)+" px";
@ -153,6 +154,12 @@ private void checkTimerCountDown_CheckedChanged(object sender, EventArgs e){
notification.ShowNotificationForSettings(true);
}
private void checkNonIntrusive_CheckedChanged(object sender, EventArgs e){
if (!Ready)return;
Config.NotificationNonIntrusiveMode = checkNonIntrusive.Checked;
}
private void comboBoxDisplay_SelectedValueChanged(object sender, EventArgs e){
if (!Ready)return;

View File

@ -119,6 +119,9 @@
<Compile Include="Core\Notification\FormNotificationTweet.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Core\Notification\FormNotificationTweet.Designer.cs">
<DependentUpon>FormNotificationTweet.cs</DependentUpon>
</Compile>
<Compile Include="Core\Notification\SoundNotification.cs" />
<Compile Include="Core\Notification\TweetNotification.cs" />
<Compile Include="Core\Other\FormAbout.cs">