diff --git a/ApplicationView/CompactSlidePanel.cs b/ApplicationView/CompactSlidePanel.cs
index 66b2baec4..e18b6af48 100644
--- a/ApplicationView/CompactSlidePanel.cs
+++ b/ApplicationView/CompactSlidePanel.cs
@@ -84,6 +84,7 @@ namespace MatterHackers.MatterControl
advancedControlsButtonFactory.invertImageLocation = true;
Button advancedControlsLinkButton = advancedControlsButtonFactory.Generate(LocalizedString.Get("Settings\n& Controls"), "icon_arrow_right_32x32.png");
+ advancedControlsLinkButton.Name = "SettingsAndControls";
advancedControlsLinkButton.ToolTipText = "Switch to Settings, Controls and Options".Localize();
advancedControlsLinkButton.Margin = new BorderDouble(right: 3);
advancedControlsLinkButton.VAnchor = VAnchor.ParentBottom;
diff --git a/MatterControl.csproj b/MatterControl.csproj
index 18e9c332b..9d7bb140b 100644
--- a/MatterControl.csproj
+++ b/MatterControl.csproj
@@ -519,5 +519,9 @@
{990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9}
InfInstaller
+
+ {9d193b5c-bef4-44b2-ad6d-597b7a2c52c5}
+ TestRunner
+
\ No newline at end of file
diff --git a/MatterControl.sln b/MatterControl.sln
index e755c1bb8..aaf3b8232 100644
--- a/MatterControl.sln
+++ b/MatterControl.sln
@@ -120,6 +120,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "X3GDriver", "..\X3GDriver\X
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Nat", "..\CloudServicesPlugin\Mono.Nat\Mono.Nat.csproj", "{F5D74163-145F-47BF-83DC-D0E07249C6CA}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestRunner", "TestRunner\TestRunner.csproj", "{9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1073,6 +1075,38 @@ Global
{F5D74163-145F-47BF-83DC-D0E07249C6CA}.Release64|x64.ActiveCfg = Release|x64
{F5D74163-145F-47BF-83DC-D0E07249C6CA}.Release64|x64.Build.0 = Release|x64
{F5D74163-145F-47BF-83DC-D0E07249C6CA}.Release64|x86.ActiveCfg = Release|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|x64.ActiveCfg = Debug|x64
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|x64.Build.0 = Debug|x64
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|x86.Build.0 = Debug|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|Any CPU.ActiveCfg = Debug64|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|Any CPU.Build.0 = Debug64|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|Mixed Platforms.ActiveCfg = Debug64|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|Mixed Platforms.Build.0 = Debug64|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|x64.ActiveCfg = Debug64|x64
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|x64.Build.0 = Debug64|x64
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|x86.ActiveCfg = Debug64|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|x86.Build.0 = Debug64|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|x64.ActiveCfg = Release|x64
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|x64.Build.0 = Release|x64
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|x86.ActiveCfg = Release|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|x86.Build.0 = Release|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|Any CPU.ActiveCfg = Release64|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|Any CPU.Build.0 = Release64|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|Mixed Platforms.ActiveCfg = Release64|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|Mixed Platforms.Build.0 = Release64|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|x64.ActiveCfg = Release64|x64
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|x64.Build.0 = Release64|x64
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|x86.ActiveCfg = Release64|Any CPU
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|x86.Build.0 = Release64|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/MatterControlApplication.cs b/MatterControlApplication.cs
index 4094ee689..fb9a1878c 100644
--- a/MatterControlApplication.cs
+++ b/MatterControlApplication.cs
@@ -39,6 +39,7 @@ using MatterHackers.MatterControl.SettingsManagement;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.PolygonMesh.Processors;
using MatterHackers.RenderOpenGl.OpenGl;
+using MatterHackers.TestRunner;
using MatterHackers.VectorMath;
using Mindscape.Raygun4Net;
using System;
@@ -48,12 +49,13 @@ using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
+using System.Threading.Tasks;
namespace MatterHackers.MatterControl
{
- public class MatterControlApplication : SystemWindow
+ public class MatterControlApplication : SystemWindow
{
- public bool RestartOnClose = false;
+ public bool RestartOnClose = false;
private static readonly Vector2 minSize = new Vector2(600, 600);
private static MatterControlApplication instance;
private string[] commandLineArgs = null;
@@ -531,6 +533,7 @@ namespace MatterHackers.MatterControl
if (firstDraw)
{
+ Task.Run((Action)ButtonClickTest);
UiThread.RunOnIdle(DoAutoConnectIfRequired);
firstDraw = false;
@@ -553,7 +556,15 @@ namespace MatterHackers.MatterControl
//msGraph.Draw(MatterHackers.Agg.Transform.Affine.NewIdentity(), graphics2D);
}
- public override void OnMouseMove(MouseEventArgs mouseEvent)
+ private void ButtonClickTest()
+ {
+ TestFramework test = new TestFramework("C:/TestImages");
+ ImageIO.SaveImageData("test.png", test.GetCurrentScreen());
+ test.Wait(2);
+ test.ClickByName("SettingsAndControls");
+ }
+
+ public override void OnMouseMove(MouseEventArgs mouseEvent)
{
if (GuiWidget.DebugBoundsUnderMouse)
{
diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp
index 8d9f6e03a..eb55baa0c 160000
--- a/Submodules/agg-sharp
+++ b/Submodules/agg-sharp
@@ -1 +1 @@
-Subproject commit 8d9f6e03a29a901ac674e6f3e3e3dd2e8aeb8f13
+Subproject commit eb55baa0c70604672943e7b6dbfa5ebb5d0a533a
diff --git a/TestRunner/TestRunner.cs b/TestRunner/TestRunner.cs
new file mode 100644
index 000000000..5e1347254
--- /dev/null
+++ b/TestRunner/TestRunner.cs
@@ -0,0 +1,189 @@
+/*
+Copyright (c) 2014, Lars Brubaker
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those
+of the authors and should not be interpreted as representing official policies,
+either expressed or implied, of the FreeBSD Project.
+*/
+
+using MatterHackers.Agg;
+using MatterHackers.Agg.Image;
+using MatterHackers.Agg.UI;
+using MatterHackers.VectorMath;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Globalization;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MatterHackers.TestRunner
+{
+ public class TestFramework
+ {
+ // P/Invoke declarations
+ [DllImport("gdi32.dll")]
+ static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int
+ wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, CopyPixelOperation rop);
+ [DllImport("user32.dll")]
+ static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);
+ [DllImport("gdi32.dll")]
+ static extern IntPtr DeleteDC(IntPtr hDc);
+ [DllImport("gdi32.dll")]
+ static extern IntPtr DeleteObject(IntPtr hDc);
+ [DllImport("gdi32.dll")]
+ static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
+ [DllImport("gdi32.dll")]
+ static extern IntPtr CreateCompatibleDC(IntPtr hdc);
+ [DllImport("gdi32.dll")]
+ static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
+ [DllImport("user32.dll")]
+ public static extern IntPtr GetDesktopWindow();
+ [DllImport("user32.dll")]
+ public static extern IntPtr GetWindowDC(IntPtr ptr);
+
+ string imageDirectory;
+
+ public TestFramework(string imageDirectory)
+ {
+ this.imageDirectory = imageDirectory;
+ }
+
+ public bool ClickByName(string widgetName, int xOffset = 0, int yOffset = 0, double upDelaySeconds = .2)
+ {
+ foreach (SystemWindow window in SystemWindow.OpenWindows)
+ {
+ GuiWidget widgetToClick = window.FindNamedChildRecursive(widgetName);
+ if (widgetToClick != null)
+ {
+ RectangleDouble childBounds = widgetToClick.TransformToParentSpace(window, widgetToClick.LocalBounds);
+ UiThread.RunOnIdle(() =>
+ window.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1,
+ childBounds.Left + xOffset, childBounds.Bottom + yOffset,
+ 0)));
+ Wait(upDelaySeconds);
+ UiThread.RunOnIdle(() =>
+ window.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 0,
+ childBounds.Left + xOffset, childBounds.Bottom + yOffset,
+ 0)));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public bool NameExists(string widgetName)
+ {
+ foreach (SystemWindow window in SystemWindow.OpenWindows)
+ {
+ GuiWidget widgetToClick = window.FindNamedChildRecursive(widgetName);
+ if (widgetToClick != null)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public ImageBuffer GetCurrentScreen()
+ {
+ ImageBuffer screenCapture = new ImageBuffer();
+
+ Size sz = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Size;
+ IntPtr hDesk = GetDesktopWindow();
+ IntPtr hSrce = GetWindowDC(hDesk);
+ IntPtr hDest = CreateCompatibleDC(hSrce);
+ IntPtr hBmp = CreateCompatibleBitmap(hSrce, sz.Width, sz.Height);
+ IntPtr hOldBmp = SelectObject(hDest, hBmp);
+ bool b = BitBlt(hDest, 0, 0, sz.Width, sz.Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
+ Bitmap bmpScreenCapture = Bitmap.FromHbitmap(hBmp);
+ SelectObject(hDest, hOldBmp);
+ DeleteObject(hBmp);
+ DeleteDC(hDest);
+ ReleaseDC(hDesk, hSrce);
+
+ //bmpScreenCapture.Save("bitmapsave.png");
+
+ screenCapture = new ImageBuffer(bmpScreenCapture.Width, bmpScreenCapture.Height, 32, new BlenderBGRA());
+ BitmapData bitmapData = bmpScreenCapture.LockBits(new Rectangle(0, 0, bmpScreenCapture.Width, bmpScreenCapture.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmpScreenCapture.PixelFormat);
+
+ int offset;
+ byte[] buffer = screenCapture.GetBuffer(out offset);
+ int bitmapDataStride = bitmapData.Stride;
+ int backBufferStrideInBytes = screenCapture.StrideInBytes();
+ int backBufferHeight = screenCapture.Height;
+ int backBufferHeightMinusOne = backBufferHeight - 1;
+
+ unsafe
+ {
+ byte* bitmapDataScan0 = (byte*)bitmapData.Scan0;
+ fixed (byte* pSourceFixed = &buffer[offset])
+ {
+ byte* pSource = bitmapDataScan0 + bitmapDataStride * backBufferHeightMinusOne;
+ byte* pDestBuffer = pSourceFixed;
+ for (int y = 0; y < screenCapture.Height; y++)
+ {
+ int* pSourceInt = (int*)pSource;
+ pSourceInt -= (bitmapDataStride * y / 4);
+
+ int* pDestBufferInt = (int*)pDestBuffer;
+ pDestBufferInt += (backBufferStrideInBytes * y / 4);
+
+ for (int x = 0; x < screenCapture.Width; x++)
+ {
+ pDestBufferInt[x] = pSourceInt[x];
+ }
+ }
+ }
+ }
+
+ bmpScreenCapture.UnlockBits(bitmapData);
+
+ bmpScreenCapture.Dispose();
+
+ return screenCapture;
+ }
+
+ public bool ImageExists(ImageBuffer image)
+ {
+ return false;
+ }
+
+ public bool ImageExists(string imageFileName)
+ {
+ return false;
+ }
+
+ public void Wait(double timeInSeconds)
+ {
+ Thread.Sleep((int)(timeInSeconds * 1000));
+ }
+ }
+}
\ No newline at end of file
diff --git a/TestRunner/TestRunner.csproj b/TestRunner/TestRunner.csproj
new file mode 100644
index 000000000..2a14e5eff
--- /dev/null
+++ b/TestRunner/TestRunner.csproj
@@ -0,0 +1,163 @@
+
+
+
+ Release
+ AnyCPU
+ 8.0.50727
+ 2.0
+ {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}
+ Library
+ Properties
+ MatterHackers.TestRunner
+ TestRunner
+
+
+
+
+ 2.0
+ v4.5
+
+
+
+ True
+ full
+ False
+ ..\bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ True
+ x86
+ false
+
+
+ pdbonly
+ True
+ ..\bin\Release\
+ TRACE
+ prompt
+ 4
+ True
+ x86
+ false
+
+
+ false
+
+
+ bin\Release64\
+ TRACE
+ true
+ true
+ pdbonly
+ x64
+ true
+ GlobalSuppressions.cs
+ prompt
+ MinimumRecommendedRules.ruleset
+ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
+ false
+ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
+ false
+ false
+ false
+
+
+ true
+ bin\Debug64\
+ DEBUG;TRACE
+ true
+ full
+ x86
+ prompt
+ false
+ false
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE
+ true
+ full
+ x64
+ prompt
+ false
+ false
+ false
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ true
+ pdbonly
+ x64
+ prompt
+ false
+ false
+ false
+
+
+ bin\x64\Release64\
+ TRACE
+ true
+ true
+ pdbonly
+ x64
+ true
+ GlobalSuppressions.cs
+ prompt
+ MinimumRecommendedRules.ruleset
+ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
+ false
+ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
+ false
+ false
+
+
+ true
+ bin\x64\Debug64\
+ DEBUG;TRACE
+ true
+ full
+ x64
+ prompt
+ false
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+ {657DBC6D-C3EA-4398-A3FA-DDB73C14F71B}
+ Agg
+
+
+ {74F6BB6C-9D02-4512-A59A-21940E35C532}
+ Gui
+
+
+ {036BCCBA-52D8-457C-84AE-8821F209FE4A}
+ ImageProcessing
+
+
+ {D3E41B4E-BFBB-44CA-94C8-95C00F754FDD}
+ VectorMath
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestRunner/app.config b/TestRunner/app.config
new file mode 100644
index 000000000..f4aff65b5
--- /dev/null
+++ b/TestRunner/app.config
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file