IPCamAppBar/IPCamAppBar/MainForm.cs

148 lines
4.9 KiB
C#

using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using IPCamLib;
using IPCamLib.Concrete;
using Microsoft.Win32;
using Newtonsoft.Json;
namespace IPCamAppBar
{
public partial class MainForm : Form
{
private readonly Config config;
private readonly AppBar appBar;
private bool paused = false;
public MainForm()
{
InitializeComponent();
// ReSharper disable once PossibleNullReferenceException
// ReSharper disable once AssignNullToNotNullAttribute
using (var file = File.OpenText(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "config.json")))
{
var serializer = new JsonSerializer();
config = (Config)serializer.Deserialize(file, typeof(Config));
}
var monitor = GetMonitor(config.AppBar.Monitor);
var position = GetAppBarPosition(config.AppBar.Side);
appBar = new AppBar(Handle);
appBar.SetPosition(monitor, position, config.AppBar.Size);
CameraViewContainer.FlowDirection =
config.AppBar.Side == ConfigSide.Left || config.AppBar.Side == ConfigSide.Right
? FlowDirection.TopDown
: FlowDirection.LeftToRight;
config.Cameras?.ForEach(AddCamera);
SystemEvents.SessionSwitch += SystemEventsOnSessionSwitch;
}
protected override void WndProc(ref Message m)
{
appBar?.HandleMessage(m);
base.WndProc(ref m);
}
private static Screen GetMonitor(int number)
{
// Since I could not find any way to get the numbers as assigned in the
// display control panel, we'll just order them left-to-right.
var orderedScreens = Screen.AllScreens.OrderBy(s => s.Bounds.Left).ToList();
// 0 means primary. Yeah. Totally not losing geek-creds for using a 1-based
// index here. No sir. 'tis a feature!
return number > 0 && number <= orderedScreens.Count
? orderedScreens[number - 1]
: Screen.PrimaryScreen;
}
private static AppBarPosition GetAppBarPosition(ConfigSide side)
{
return side switch
{
ConfigSide.Top => AppBarPosition.Top,
ConfigSide.Bottom => AppBarPosition.Bottom,
ConfigSide.Left => AppBarPosition.Left,
ConfigSide.Right => AppBarPosition.Right,
_ => throw new ArgumentOutOfRangeException(nameof(side), side, @"Invalid side value")
};
}
private void AddCamera(ConfigCamera configCamera)
{
ICamera camera = configCamera.Type switch
{
ConfigCameraType.HTTPMJPEG => new HTTPMJPEGStreamCamera(new Uri(configCamera.URL)),
ConfigCameraType.RTSP => new RTSPStreamCamera(new Uri(configCamera.URL), configCamera.Width, configCamera.Height),
_ => throw new ArgumentOutOfRangeException($"Camera type in configuration is not valid: {configCamera.Type}")
};
var margin = new Padding(0);
if (CameraViewContainer.FlowDirection == FlowDirection.LeftToRight)
margin.Right = config.AppBar.Spacing;
else
margin.Bottom = config.AppBar.Spacing;
var view = new CameraView(camera, configCamera.OverlayDateTime)
{
Width = configCamera.Width,
Height = configCamera.Height,
Margin = margin
};
CameraViewContainer.Controls.Add(view);
}
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
appBar.Dispose();
}
private void CloseToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void SystemEventsOnSessionSwitch(object sender, SessionSwitchEventArgs e)
{
if (InvokeRequired)
{
Invoke(new Action(() => SystemEventsOnSessionSwitch(sender, e)));
return;
}
var pause = e.Reason == SessionSwitchReason.ConsoleDisconnect ||
e.Reason == SessionSwitchReason.RemoteDisconnect ||
e.Reason == SessionSwitchReason.SessionLock ||
e.Reason == SessionSwitchReason.SessionLogoff;
if (pause == paused)
return;
foreach (var control in CameraViewContainer.Controls)
{
if (control is CameraView cameraView)
cameraView.SetPaused(pause);
}
paused = pause;
}
}
}