Skip to content

Commit

Permalink
Added new utility: Measure 1.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
flexplate committed Nov 1, 2019
1 parent 11ff58f commit d7a5ad5
Show file tree
Hide file tree
Showing 11 changed files with 570 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Measure/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
85 changes: 85 additions & 0 deletions Measure/Measure.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C32135A3-AFBB-4A3D-8AC6-B07CF94BBCBD}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Measure</RootNamespace>
<AssemblyName>Measure</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Overlay.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Properties\Strings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Strings.resx</DependentUpon>
</Compile>
<EmbeddedResource Include="Properties\Strings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
190 changes: 190 additions & 0 deletions Measure/Overlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Measure
{
class Overlay : Form
{
Point start;
Point end;
bool drawing;

Pen linePen = new Pen(new SolidBrush(Color.FromArgb(255, Color.Magenta)), 1);
Font Segoe = new Font("Segoe UI", 11, FontStyle.Regular);

Bitmap screenshot = null;

public Overlay()
{
this.WindowState = FormWindowState.Maximized;
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = Color.Black;
this.DoubleBuffered = true;

this.MouseDown += Overlay_MouseDown;
this.MouseUp += Overlay_MouseUp;
this.MouseMove += Overlay_MouseMove;
this.Paint += Overlay_Paint;
this.KeyUp += Overlay_KeyUp;

}

private void InitializeComponent()
{
this.Name = "Measure";
this.ShowInTaskbar = false;
this.ResumeLayout(false);
}

/// <summary>
/// Set start point as we initially click
/// </summary>
private void Overlay_MouseDown(object sender, MouseEventArgs e)
{
start = e.Location;
drawing = true;
}

/// <summary>
/// Stop drawing as we release the mouse.
/// </summary>
private void Overlay_MouseUp(object sender, MouseEventArgs e)
{
drawing = false;
}

/// <summary>
/// If we're drawing and moving the mouse, we set the end point to the current cursor location.
/// </summary>
private void Overlay_MouseMove(object sender, MouseEventArgs e)
{
if (drawing)
{
end = e.Location;
// Cause active area of form to be redrawn
this.Invalidate();
}
}

/// <summary>
/// Draw
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Overlay_Paint(object sender, PaintEventArgs e)
{
// Vertical line
e.Graphics.DrawLine(linePen, start.X, start.Y, start.X, end.Y);

// Horizontal line
e.Graphics.DrawLine(linePen, start.X, end.Y, end.X, end.Y);

// Diagonal line
e.Graphics.DrawLine(linePen, start.X, start.Y, end.X, end.Y);

// Boxes to show end points
e.Graphics.FillPolygon(Brushes.LimeGreen, PointToBox(start));
e.Graphics.FillPolygon(Brushes.LimeGreen, PointToBox(end));

// Text coordinates of start- and endpoints.
e.Graphics.DrawString(SimpleCoords(start), Segoe, Brushes.White, start);
e.Graphics.DrawString(SimpleCoords(end), Segoe, Brushes.White, end);

// Line lengths
// Width
int dx = end.X - start.X;
e.Graphics.DrawString(Math.Abs(dx) + "px", Segoe, Brushes.White, start.X + dx / 2, end.Y);

// Height
int dy = end.Y - start.Y;
e.Graphics.DrawString(Math.Abs(dy) + "px", Segoe, Brushes.White, start.X, start.Y + dy / 2);

// Hypotenuse length
double hyp = Math.Round(Math.Sqrt(dx * dx + dy * dy), 0, MidpointRounding.AwayFromZero);
e.Graphics.DrawString(hyp + "px", Segoe, Brushes.White, start.X + dx / 2, start.Y + dy / 2);

}

/// <summary>
/// Capture the escape or Q keys to exit.
/// </summary>
private void Overlay_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape || e.KeyCode == Keys.Q)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
}

/// <summary>
/// Convert a single point into a 5x5 pixel box
/// </summary>
/// <param name="point">Point to centre box on.</param>
/// <returns>An array of points making a 5x5 rectangle centred on a specified point.</returns>
private Point[] PointToBox(Point point)
{
return new Point[] {
new Point(point.X - 2, point.Y - 2 ),
new Point(point.X + 2, point.Y - 2 ),
new Point(point.X + 2, point.Y + 2 ),
new Point(point.X - 2, point.Y + 2 )
};
}

/// <summary>
/// Override the background painting to fake a translucent form background.
/// Draw instructions at this point to avoid redrawing every frame.
/// </summary>
protected override void OnPaintBackground(PaintEventArgs e)
{
// Take screenshot the first time. Won't update the screen, but otherwise it fades to black every frame as we take successively darker screenshots.
if (screenshot == null)
{
using (Image image = new Bitmap(this.Width, this.Height))
{
using (Graphics Surface = Graphics.FromImage(image))
{
var BackgroundBrush = new SolidBrush(Color.FromArgb(128, Color.Black));
var DarkerBrush = new SolidBrush(Color.FromArgb(192, Color.Black));

Surface.CopyFromScreen(0, 0, 0, 0, this.Size);
Surface.FillRectangle(BackgroundBrush, this.DisplayRectangle);

// Measure and draw instructions. Draw a darker rectangle behind them.
Size TextSize = ExpandSize(Size.Round(e.Graphics.MeasureString(Properties.Strings.Instructions, Segoe)), 5);
Point TextOrigin = Point.Round(new PointF(this.Width / 2 - TextSize.Width / 2, this.Height - TextSize.Height - 10));
var TextBox = new Rectangle(TextOrigin, TextSize);
Surface.FillRectangle(DarkerBrush, TextBox);
Surface.DrawString(Properties.Strings.Instructions, Segoe, Brushes.White, TextBox);

}
screenshot = new Bitmap(image);
}
}
e.Graphics.DrawImage(screenshot, 0, 0);
}

/// <summary>
/// Get shorter version of the coordinates of a Point (or PointF).
/// </summary>
/// <param name="point">Point to return coords of.</param>
/// <returns>Coordinates in the format "X,Y".</returns>
public string SimpleCoords(PointF point)
{
return point.X + "," + point.Y;
}

/// <summary>
/// Expand a given size by a given amount.
/// </summary>
/// <param name="size">Size to base our new size on.</param>
/// <param name="expandBy">Amount to change dimensions by.</param>
public Size ExpandSize(Size size, int expandBy)
{
return new Size(size.Width + expandBy, size.Height + expandBy);
}

}
}
22 changes: 22 additions & 0 deletions Measure/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Measure
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Overlay());
}
}
}
26 changes: 26 additions & 0 deletions Measure/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Measure")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Measure")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("c32135a3-afbb-4a3d-8ac6-b07cf94bbcbd")]


[assembly: AssemblyVersion("1.0.*")]
30 changes: 30 additions & 0 deletions Measure/Properties/Settings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Measure/Properties/Settings.settings
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
Loading

0 comments on commit d7a5ad5

Please sign in to comment.