diff --git a/VAR.Toolbox/UI/Tools/PnlActivity.Designer.cs b/VAR.Toolbox/UI/Tools/PnlActivity.Designer.cs
new file mode 100644
index 0000000..2877cdc
--- /dev/null
+++ b/VAR.Toolbox/UI/Tools/PnlActivity.Designer.cs
@@ -0,0 +1,108 @@
+namespace VAR.Toolbox.UI.Tools
+{
+ partial class PnlActivity
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.grpActivity = new System.Windows.Forms.GroupBox();
+ this.lblActive = new System.Windows.Forms.Label();
+ this.lblActiveWindowTitle = new System.Windows.Forms.Label();
+ this.txtCurrentActivity = new System.Windows.Forms.TextBox();
+ this.timTicker = new System.Windows.Forms.Timer(this.components);
+ this.grpActivity.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // grpActivity
+ //
+ this.grpActivity.Controls.Add(this.lblActive);
+ this.grpActivity.Controls.Add(this.lblActiveWindowTitle);
+ this.grpActivity.Controls.Add(this.txtCurrentActivity);
+ this.grpActivity.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.grpActivity.Location = new System.Drawing.Point(0, 0);
+ this.grpActivity.Name = "grpActivity";
+ this.grpActivity.Size = new System.Drawing.Size(200, 125);
+ this.grpActivity.TabIndex = 0;
+ this.grpActivity.TabStop = false;
+ this.grpActivity.Text = "Activity";
+ //
+ // lblActive
+ //
+ this.lblActive.AutoSize = true;
+ this.lblActive.Location = new System.Drawing.Point(7, 102);
+ this.lblActive.Name = "lblActive";
+ this.lblActive.Size = new System.Drawing.Size(37, 13);
+ this.lblActive.TabIndex = 2;
+ this.lblActive.Text = "Active";
+ //
+ // lblActiveWindowTitle
+ //
+ this.lblActiveWindowTitle.AutoSize = true;
+ this.lblActiveWindowTitle.Location = new System.Drawing.Point(7, 85);
+ this.lblActiveWindowTitle.Name = "lblActiveWindowTitle";
+ this.lblActiveWindowTitle.Size = new System.Drawing.Size(96, 13);
+ this.lblActiveWindowTitle.TabIndex = 1;
+ this.lblActiveWindowTitle.Text = "ActiveWindowTitle";
+ //
+ // txtCurrentActivity
+ //
+ this.txtCurrentActivity.Location = new System.Drawing.Point(7, 20);
+ this.txtCurrentActivity.Multiline = true;
+ this.txtCurrentActivity.Name = "txtCurrentActivity";
+ this.txtCurrentActivity.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+ this.txtCurrentActivity.Size = new System.Drawing.Size(187, 58);
+ this.txtCurrentActivity.TabIndex = 0;
+ //
+ // timTicker
+ //
+ this.timTicker.Enabled = true;
+ this.timTicker.Interval = 1000;
+ this.timTicker.Tick += new System.EventHandler(this.TimTicker_Tick);
+ //
+ // PnlActivity
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.grpActivity);
+ this.Margin = new System.Windows.Forms.Padding(0);
+ this.Name = "PnlActivity";
+ this.Size = new System.Drawing.Size(200, 125);
+ this.grpActivity.ResumeLayout(false);
+ this.grpActivity.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.GroupBox grpActivity;
+ private System.Windows.Forms.Label lblActive;
+ private System.Windows.Forms.Label lblActiveWindowTitle;
+ private System.Windows.Forms.TextBox txtCurrentActivity;
+ private System.Windows.Forms.Timer timTicker;
+ }
+}
diff --git a/VAR.Toolbox/UI/Tools/PnlActivity.cs b/VAR.Toolbox/UI/Tools/PnlActivity.cs
new file mode 100644
index 0000000..04c2664
--- /dev/null
+++ b/VAR.Toolbox/UI/Tools/PnlActivity.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Windows.Forms;
+using VAR.Json;
+using VAR.Toolbox.Code.Windows;
+
+namespace VAR.Toolbox.UI.Tools
+{
+ public partial class PnlActivity : UserControl, IToolPanel
+ {
+ public PnlActivity()
+ {
+ InitializeComponent();
+ }
+
+ private void TimTicker_Tick(object sender, EventArgs e)
+ {
+ if (DesignMode) { return; }
+ timTicker.Stop();
+
+ string activeWindowTitle = User32.GetActiveWindowTitle();
+ bool active = Win32.GetLastInputTime() < 2;
+ DateTime date = DateTime.UtcNow;
+
+ lblActiveWindowTitle.Text = activeWindowTitle;
+ lblActive.Text = active ? "Active" : "Inactive";
+
+ Activity_Register(activeWindowTitle, active, date);
+
+ timTicker.Start();
+ }
+
+ private class ActivityPoint
+ {
+ public string ActiveWindowTitle { get; set; }
+ public bool Active { get; set; }
+ public DateTime Date { get; set; }
+ }
+
+ private DateTime _currentDate = DateTime.MinValue;
+ private readonly List _currentActivityPoints = new List();
+
+ private const int SecondsPerFrame = 30;
+
+ private void Activity_Register(string activeWindowTitle, bool active, DateTime date)
+ {
+ TimeSpan diffTime = date - _currentDate;
+ if (diffTime.TotalSeconds > SecondsPerFrame)
+ {
+ Activity_EndFrame();
+ _currentActivityPoints.Clear();
+ _currentDate = date;
+ }
+
+ _currentActivityPoints.Add(new ActivityPoint
+ {
+ ActiveWindowTitle = activeWindowTitle,
+ Active = active,
+ Date = date,
+ });
+ }
+
+
+ private class ActivityFrame
+ {
+ public DateTime StartDate { get; set; }
+ public DateTime EndDate { get; set; }
+ public string CurrentActivity { get; set; }
+ public List ActiveWindowTitles { get; set; } = new List();
+ public float ActivityFactor { get; set; }
+ }
+
+ private void Activity_EndFrame()
+ {
+ if (_currentActivityPoints.Count == 0)
+ {
+ return;
+ }
+
+ // Prepare frame
+ ActivityFrame frame = new ActivityFrame
+ {
+ StartDate = _currentActivityPoints.Min(ap => ap.Date),
+ EndDate = _currentActivityPoints.Max(ap => ap.Date),
+ CurrentActivity = txtCurrentActivity.Text,
+ ActiveWindowTitles = _currentActivityPoints.Select(ap => ap.ActiveWindowTitle).Distinct().ToList(),
+ ActivityFactor = _currentActivityPoints.Count(ap => ap.Active) / (float)_currentActivityPoints.Count,
+ };
+
+ // Write frame
+ JsonWriter jsonWriter = new Json.JsonWriter();
+ string line = jsonWriter.Write(frame);
+ try
+ {
+ StreamWriter outStream = GetOutputStreamWritter();
+ outStream.WriteLine(line);
+ CloseOutputStreamWritter(outStream);
+ }
+ catch (Exception) { /* Nom Nom Nom */}
+ }
+
+ private static StreamWriter GetOutputStreamWritter()
+ {
+ try
+ {
+ string location = System.Reflection.Assembly.GetEntryAssembly().Location;
+ string path = Path.GetDirectoryName(location);
+
+ string fileOut = string.Format("{0}/Activity.{1}.txt", path,
+ DateTime.UtcNow.ToString("yyyy-MM-dd"));
+ return File.AppendText(fileOut);
+ }
+ catch (Exception)
+ {
+ return null;
+ }
+ }
+
+ private static void CloseOutputStreamWritter(StreamWriter stream)
+ {
+ if (stream != null)
+ {
+ stream.Close();
+ }
+ }
+
+
+ }
+}
diff --git a/VAR.Toolbox/VAR.Toolbox.csproj b/VAR.Toolbox/VAR.Toolbox.csproj
index a34cba0..5cb326b 100644
--- a/VAR.Toolbox/VAR.Toolbox.csproj
+++ b/VAR.Toolbox/VAR.Toolbox.csproj
@@ -193,6 +193,12 @@
FrmWebcam.cs
+
+ UserControl
+
+
+ PnlActivity.cs
+
UserControl
@@ -214,7 +220,6 @@
-