DisplayMagician/DisplayMagicianShared/UserControls/DisplayView.cs
Terry MacDonald 9e1ef4a095 [WIP] First working WiX installer
Installer works, but there are a few issues with it.
- It doesn't register the DesktopBackground COM server
- It doesn't create a start menu shortcut with the AUMID
- It doesn't check for .Net Framework 4.8 or later
- It doesn't try to install .Net Framework 4.8 or later if not there
- It doesn't have any customised backgrounds...
- It doesn't ask to run DisplayMagician when install is finished
2020-12-20 20:42:04 +13:00

248 lines
9.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Drawing;
using System.Windows.Forms;
using DisplayMagicianShared.Topology;
namespace DisplayMagicianShared.UserControls
{
public partial class DisplayView : UserControl
{
private ProfileItem _profile;
public DisplayView()
{
InitializeComponent();
ResizeRedraw = true;
}
public int PaddingX { get; set; } = 100;
public int PaddingY { get; set; } = 100;
public ProfileItem Profile
{
get => _profile;
set
{
_profile = value;
Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (_profile != null)
{
DrawView(e.Graphics);
}
else
{
DrawEmptyView(e.Graphics);
}
}
private void DrawPath(Graphics g, Path path)
{
var res = ProfileIcon.NormalizeResolution(path);
var rect = new Rectangle(path.Position, res);
g.FillRectangle(new SolidBrush(Color.FromArgb(15, Color.White)), rect);
g.DrawRectangle(Pens.Black, rect);
DrawString(g, path.Position.IsEmpty ? "[Primary]" : $"[{path.Position.X}, {path.Position.Y}]", rect.Size,
new PointF(rect.X + PaddingY / 2, rect.Y + PaddingY / 2), StringAlignment.Near, StringAlignment.Near);
var str = $"DISPLAY #{path.SourceId + 1}{Environment.NewLine}{rect.Width}×{rect.Height}";
var strSize = DrawString(g, str, rect.Size, new PointF(rect.X - PaddingX / 2, rect.Y + PaddingY / 2),
StringAlignment.Near, StringAlignment.Far);
var rows = rect.Width < rect.Height ? path.TargetDisplays.Length : 1;
var cols = rect.Width >= rect.Height ? path.TargetDisplays.Length : 1;
for (var i = 0; i < path.TargetDisplays.Length; i++)
{
DrawTarget(g, path, path.TargetDisplays[i],
new Rectangle(rect.X + PaddingX, rect.Y + strSize.Height + PaddingY, rect.Width - 2 * PaddingX,
rect.Height - strSize.Height - 2 * PaddingY),
rows > 1 ? i : 0, cols > 1 ? i : 0, rows, cols);
}
}
private Size DrawString(
Graphics g,
string str,
SizeF drawingSize = default(SizeF),
PointF? drawingPoint = null,
StringAlignment vertical = StringAlignment.Center,
StringAlignment horizontal = StringAlignment.Center)
{
var format = new StringFormat(StringFormat.GenericTypographic)
{
Alignment = horizontal,
LineAlignment = vertical,
FormatFlags = StringFormatFlags.NoClip
};
var stringSize = g.MeasureString(str, Font, drawingSize, format);
if (drawingPoint != null)
{
g.DrawString(str, Font, new SolidBrush(ForeColor), new RectangleF(drawingPoint.Value, drawingSize),
format);
}
return new Size((int) stringSize.Width, (int) stringSize.Height);
}
private void DrawSurroundTopology(Graphics g, PathTarget target, Rectangle rect)
{
g.DrawRectangle(Pens.Black, rect);
var targetSize = new Size(rect.Width / target.SurroundTopology.Columns,
rect.Height / target.SurroundTopology.Rows);
for (var i = 0; i < target.SurroundTopology.Displays.Length; i++)
{
var display = target.SurroundTopology.Displays[i];
var row = i / target.SurroundTopology.Columns;
var col = i % target.SurroundTopology.Columns;
var targetPosition = new Point(targetSize.Width * col + rect.X, targetSize.Height * row + rect.Y);
var targetRect = new Rectangle(targetPosition, targetSize);
g.DrawRectangle(Pens.Black, targetRect);
switch (display.Rotation)
{
case Rotation.Rotate90:
DrawString(g, "90°", targetRect.Size,
new PointF(targetRect.X - PaddingX / 2, targetRect.Y + PaddingY / 2), StringAlignment.Near,
StringAlignment.Far);
break;
case Rotation.Rotate180:
DrawString(g, "180°", targetRect.Size,
new PointF(targetRect.X - PaddingX / 2, targetRect.Y + PaddingY / 2), StringAlignment.Near,
StringAlignment.Far);
break;
case Rotation.Rotate270:
DrawString(g, "270°", targetRect.Size,
new PointF(targetRect.X - PaddingX / 2, targetRect.Y + PaddingY / 2), StringAlignment.Near,
StringAlignment.Far);
break;
}
if (!display.Overlap.IsEmpty)
{
DrawString(g, $"[{-display.Overlap.X}, {-display.Overlap.Y}]", targetRect.Size,
new PointF(targetRect.X + PaddingY / 2, targetRect.Y + PaddingY / 2), StringAlignment.Near,
StringAlignment.Near);
}
// Invert to real monitor resolution
var res = ProfileIcon.NormalizeResolution(target.SurroundTopology.Resolution, display.Rotation);
var str = $"{display.DisplayName}{Environment.NewLine}{res.Width}×{res.Height}";
DrawString(g, str, targetRect.Size, targetRect.Location);
}
}
private void DrawTarget(
Graphics g,
Path path,
PathTarget target,
Rectangle rect,
int row,
int col,
int rows,
int cols)
{
var targetSize = new Size(rect.Width / cols, rect.Height / rows);
var targetPosition = new Point(targetSize.Width * col + rect.X, targetSize.Height * row + rect.Y);
var targetRect = new Rectangle(targetPosition, targetSize);
if (target.SurroundTopology != null)
{
g.FillRectangle(new SolidBrush(Color.FromArgb(150, 106, 185, 0)), targetRect);
}
//else if (target.EyefinityTopology != null)
// g.FillRectangle(new SolidBrush(Color.FromArgb(150, 99, 0, 0)), targetRect);
else if (path.TargetDisplays.Length > 1)
{
g.FillRectangle(new SolidBrush(Color.FromArgb(150, 255, 97, 27)), targetRect);
}
else if (path.Position == Point.Empty)
{
g.FillRectangle(new SolidBrush(Color.FromArgb(150, 0, 174, 241)), targetRect);
}
else
{
g.FillRectangle(new SolidBrush(Color.FromArgb(255, 155, 155, 155)), targetRect);
}
g.DrawRectangle(Pens.Black, targetRect);
var str = $"{target.DisplayName}{Environment.NewLine}{path.Resolution.Width}×{path.Resolution.Height}";
switch (target.Rotation)
{
case Rotation.Rotate90:
DrawString(g, "90°", targetRect.Size,
new PointF(targetRect.X - PaddingX / 2, targetRect.Y + PaddingY / 2), StringAlignment.Near,
StringAlignment.Far);
break;
case Rotation.Rotate180:
DrawString(g, "180°", targetRect.Size,
new PointF(targetRect.X - PaddingX / 2, targetRect.Y + PaddingY / 2), StringAlignment.Near,
StringAlignment.Far);
break;
case Rotation.Rotate270:
DrawString(g, "270°", targetRect.Size,
new PointF(targetRect.X - PaddingX / 2, targetRect.Y + PaddingY / 2), StringAlignment.Near,
StringAlignment.Far);
break;
}
if (target.SurroundTopology != null)
{
var strSize = DrawString(g, str, targetRect.Size,
new PointF(targetRect.X + PaddingX / 2, targetRect.Y + PaddingY / 2),
StringAlignment.Near, StringAlignment.Near);
DrawSurroundTopology(g, target,
new Rectangle(
targetRect.X + PaddingX,
targetRect.Y + strSize.Height + PaddingY,
targetRect.Width - 2 * PaddingX,
targetRect.Height - strSize.Height - 2 * PaddingY));
}
else
{
DrawString(g, str, targetRect.Size, targetRect.Location);
}
}
private void DrawView(Graphics g)
{
var viewSize = ProfileIcon.CalculateViewSize(_profile.Paths, true, PaddingX, PaddingY);
var factor = Math.Min(Width / viewSize.Width, Height / viewSize.Height);
g.ScaleTransform(factor, factor);
var xOffset = (Width / factor - viewSize.Width) / 2f;
var yOffset = (Height / factor - viewSize.Height) / 2f;
g.TranslateTransform(-viewSize.X + xOffset, -viewSize.Y + yOffset);
foreach (var path in _profile.Paths)
{
DrawPath(g, path);
}
}
private void DrawEmptyView(Graphics g)
{
RectangleF rect = g.VisibleClipBounds;
g.FillRectangle(new SolidBrush(Color.FromArgb(15, Color.White)), rect);
g.DrawRectangle(Pens.Black, rect.X, rect.Y, rect.Width, rect.Height);
}
}
}