├── Licence.txt
├── README.md
├── bin
└── Protractor_v1_1.xap
├── doc
├── ApplicationIcon.xcf
├── ApplicationIconLarge.xcf
├── length_measure.jpg
├── length_measure_small.png
└── settings.jpg
└── src
├── Protractor.sln
└── Protractor
├── App.xaml
├── App.xaml.cs
├── ApplicationIcon.png
├── Background.png
├── BrowserMouseHelper.cs
├── MainPage.xaml
├── MainPage.xaml.cs
├── Properties
├── AppManifest.xml
├── AssemblyInfo.cs
└── WMAppManifest.xml
├── Protractor.csproj
├── SplashScreenImage.jpg
├── html
├── index.html
├── papergrid.png
├── script.js
├── settings.png
└── style.css
├── index.html
├── script.js
└── style.css
/Licence.txt:
--------------------------------------------------------------------------------
1 | Copyright © 2012-2014 Microsoft Mobile Oy. All rights reserved.
2 |
3 | Microsoft is a registered trademark of Microsoft Corporation. Nokia and HERE are
4 | trademarks and/or registered trademarks of Nokia Corporation. Other product and
5 | company names mentioned herein may be trademarks or trade names of their
6 | respective owners.
7 |
8 |
9 | License
10 |
11 | Subject to the conditions below, you may use, copy, modify and/or merge copies
12 | of this software and associated content and documentation files (the ”Software”)
13 | to test, develop, publish, distribute, sub-license and/or sell new software
14 | derived from or incorporating the Software, solely in connection with Microsoft
15 | Mobile devices (however branded). Some of the documentation, content and/or
16 | software may be licensed under open source software or other licenses. To the
17 | extent such documentation, content and/or software are included, those licenses
18 | and/or other terms and conditions shall apply in addition and/or instead of this
19 | notice. The exact terms of the licenses, disclaimers, acknowledgements and
20 | notices are reproduced in the materials provided, or in other obvious locations.
21 | No other license to any other intellectual property rights is granted herein.
22 |
23 | This file, unmodified, shall be included with all copies or substantial portions
24 | of the Software that are distributed in source code form.
25 |
26 | The Software cannot constitute the primary value of any new software derived
27 | from or incorporating the Software.
28 |
29 | Any person dealing with the Software shall not misrepresent the source of the
30 | Software.
31 |
32 |
33 | Disclaimer
34 |
35 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
37 | FOR A PARTICULAR PURPOSE, QUALITY AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES (INCLUDING,
39 | WITHOUT LIMITATION, DIRECT, SPECIAL, INDIRECT, PUNITIVE, CONSEQUENTIAL,
40 | EXEMPLARY AND/ OR INCIDENTAL DAMAGES) OR OTHER LIABILITY, WHETHER IN AN ACTION
41 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
42 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 |
44 | Microsoft Mobile Oy retains the right to make changes to this document at any
45 | time, without notice.
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Protractor
2 | ==========
3 |
4 | HTML5 application for Windows Phone that allows the screen to be used as
5 | protractor/ruler to measure lengths and angles. The Protractor application
6 | utilizes HTML5 Canvas element to do all of the drawing. The HTML content is
7 | run in the WebBrowser element in Silverlight.
8 |
9 | 
10 |
11 | This project is hosted in GitHub: https://github.com/Microsoft/protractor
12 |
13 | Developed with Microsoft Visual Studio 2010 Express for Windows Phone. Tested
14 | with Nokia Lumia 800.
15 |
16 | **What's new in version 1.1**
17 |
18 | The Protractor now supports wider range of Windows Phones that just Nokia Lumia
19 | 800, as it is possible to adjust the screen length to set the correct spacing to
20 | ruler. Now it is also possible to set the ruler length units between inches and
21 | millimeters.
22 |
23 |
24 | License
25 | --------------------------------------------------------------------------------
26 |
27 | See the license text file delivered with this project. The license is also
28 | available online at
29 | https://github.com/Microsoft/protractor/blob/master/Licence.txt
30 |
31 |
32 | Version history
33 | --------------------------------------------------------------------------------
34 |
35 | * Version 1.1: Wider device support. The units of measures expanded.
36 | * Version 1.0: The initial release.
37 |
--------------------------------------------------------------------------------
/bin/Protractor_v1_1.xap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/bin/Protractor_v1_1.xap
--------------------------------------------------------------------------------
/doc/ApplicationIcon.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/doc/ApplicationIcon.xcf
--------------------------------------------------------------------------------
/doc/ApplicationIconLarge.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/doc/ApplicationIconLarge.xcf
--------------------------------------------------------------------------------
/doc/length_measure.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/doc/length_measure.jpg
--------------------------------------------------------------------------------
/doc/length_measure_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/doc/length_measure_small.png
--------------------------------------------------------------------------------
/doc/settings.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/doc/settings.jpg
--------------------------------------------------------------------------------
/src/Protractor.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010 Express for Windows Phone
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Protractor", "Protractor\Protractor.csproj", "{580079E8-E581-4310-869D-A0924A5BBEB0}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {580079E8-E581-4310-869D-A0924A5BBEB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {580079E8-E581-4310-869D-A0924A5BBEB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {580079E8-E581-4310-869D-A0924A5BBEB0}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
15 | {580079E8-E581-4310-869D-A0924A5BBEB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
16 | {580079E8-E581-4310-869D-A0924A5BBEB0}.Release|Any CPU.Build.0 = Release|Any CPU
17 | {580079E8-E581-4310-869D-A0924A5BBEB0}.Release|Any CPU.Deploy.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/src/Protractor/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/Protractor/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Windows;
6 | using System.Windows.Controls;
7 | using System.Windows.Documents;
8 | using System.Windows.Input;
9 | using System.Windows.Media;
10 | using System.Windows.Media.Animation;
11 | using System.Windows.Navigation;
12 | using System.Windows.Shapes;
13 | using Microsoft.Phone.Controls;
14 | using Microsoft.Phone.Shell;
15 |
16 | namespace Protractor_WP
17 | {
18 | public partial class App : Application
19 | {
20 | ///
21 | /// Provides easy access to the root frame of the Phone Application.
22 | ///
23 | /// The root frame of the Phone Application.
24 | public PhoneApplicationFrame RootFrame { get; private set; }
25 |
26 | ///
27 | /// Constructor for the Application object.
28 | ///
29 | public App()
30 | {
31 | // Global handler for uncaught exceptions.
32 | UnhandledException += Application_UnhandledException;
33 |
34 | // Standard Silverlight initialization
35 | InitializeComponent();
36 |
37 | // Phone-specific initialization
38 | InitializePhoneApplication();
39 |
40 | // Show graphics profiling information while debugging.
41 | if (System.Diagnostics.Debugger.IsAttached)
42 | {
43 | // Display the current frame rate counters.
44 | Application.Current.Host.Settings.EnableFrameRateCounter = false;
45 |
46 | // Show the areas of the app that are being redrawn in each frame.
47 | //Application.Current.Host.Settings.EnableRedrawRegions = true;
48 |
49 | // Enable non-production analysis visualization mode,
50 | // which shows areas of a page that are handed off to GPU with a colored overlay.
51 | //Application.Current.Host.Settings.EnableCacheVisualization = true;
52 |
53 | // Disable the application idle detection by setting the UserIdleDetectionMode property of the
54 | // application's PhoneApplicationService object to Disabled.
55 | // Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
56 | // and consume battery power when the user is not using the phone.
57 | PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
58 | }
59 | }
60 |
61 | // Code to execute when the application is launching (eg, from Start)
62 | // This code will not execute when the application is reactivated
63 | private void Application_Launching(object sender, LaunchingEventArgs e)
64 | {
65 | }
66 |
67 | // Code to execute when the application is activated (brought to foreground)
68 | // This code will not execute when the application is first launched
69 | private void Application_Activated(object sender, ActivatedEventArgs e)
70 | {
71 | }
72 |
73 | // Code to execute when the application is deactivated (sent to background)
74 | // This code will not execute when the application is closing
75 | private void Application_Deactivated(object sender, DeactivatedEventArgs e)
76 | {
77 | }
78 |
79 | // Code to execute when the application is closing (eg, user hit Back)
80 | // This code will not execute when the application is deactivated
81 | private void Application_Closing(object sender, ClosingEventArgs e)
82 | {
83 | }
84 |
85 | // Code to execute if a navigation fails
86 | private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
87 | {
88 | if (System.Diagnostics.Debugger.IsAttached)
89 | {
90 | // A navigation has failed; break into the debugger
91 | System.Diagnostics.Debugger.Break();
92 | }
93 | }
94 |
95 | // Code to execute on Unhandled Exceptions
96 | private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
97 | {
98 | if (System.Diagnostics.Debugger.IsAttached)
99 | {
100 | // An unhandled exception has occurred; break into the debugger
101 | System.Diagnostics.Debugger.Break();
102 | }
103 | }
104 |
105 | #region Phone application initialization
106 |
107 | // Avoid double-initialization
108 | private bool phoneApplicationInitialized = false;
109 |
110 | // Do not add any additional code to this method
111 | private void InitializePhoneApplication()
112 | {
113 | if (phoneApplicationInitialized)
114 | return;
115 |
116 | // Create the frame but don't set it as RootVisual yet; this allows the splash
117 | // screen to remain active until the application is ready to render.
118 | RootFrame = new PhoneApplicationFrame();
119 | RootFrame.Navigated += CompleteInitializePhoneApplication;
120 |
121 | // Handle navigation failures
122 | RootFrame.NavigationFailed += RootFrame_NavigationFailed;
123 |
124 | // Ensure we don't initialize again
125 | phoneApplicationInitialized = true;
126 | }
127 |
128 | // Do not add any additional code to this method
129 | private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
130 | {
131 | // Set the root visual to allow the application to render
132 | if (RootVisual != RootFrame)
133 | RootVisual = RootFrame;
134 |
135 | // Remove this handler since it is no longer needed
136 | RootFrame.Navigated -= CompleteInitializePhoneApplication;
137 | }
138 |
139 | #endregion
140 | }
141 | }
--------------------------------------------------------------------------------
/src/Protractor/ApplicationIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/src/Protractor/ApplicationIcon.png
--------------------------------------------------------------------------------
/src/Protractor/Background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/src/Protractor/Background.png
--------------------------------------------------------------------------------
/src/Protractor/BrowserMouseHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Windows;
3 | using System.Windows.Controls;
4 | using Microsoft.Phone.Controls;
5 | using System.Windows.Input;
6 | using System.Diagnostics;
7 | using System.Windows.Media;
8 | using System;
9 | using System.Collections.Generic;
10 |
11 | namespace Protractor_WP
12 | {
13 | public class BrowserMouseHelper
14 | {
15 | /**
16 | *
17 | * Full Script below, in use it is minified.
18 | */
19 | /*
20 | private static string mouseScript =
21 | @"(function(win,doc){
22 | Object.defineProperty( MouseEvent.prototype, 'pageX', {
23 | configurable: true,
24 | get: function(){ return this.clientX }
25 | });
26 | Object.defineProperty( MouseEvent.prototype, 'pageY', {
27 | configurable: true,
28 | get: function(){ return this.clientY }
29 | });
30 |
31 | win.onNativeMouseEvent = function(type,x,y){
32 | try {
33 | var xMod = screen.logicalXDPI / screen.deviceXDPI;
34 | var yMod = screen.logicalYDPI / screen.deviceYDPI;
35 | var evt = doc.createEvent('MouseEvents');
36 | var xPos = doc.body.scrollLeft + Math.round(xMod * x);
37 | var yPos = doc.body.scrollTop + Math.round(yMod * y);
38 | var element = doc.elementFromPoint(xPos,yPos);
39 | evt.initMouseEvent(type, true, true, win, 1, xPos, yPos, xPos, yPos, false, false, false, false, 0, element);
40 | var canceled = element ? !element.dispatchEvent(evt) : !doc.dispatchEvent(evt);
41 | return canceled ? 'true' : 'false';
42 | }
43 | catch(e) { return e;}
44 | }
45 | })(window,document);";
46 | */
47 |
48 | private static string MinifiedMouseScript = "(function(f,a){Object.defineProperty(MouseEvent.prototype,'pageX',{configurable:!0,get:function(){return this.clientX}});Object.defineProperty(MouseEvent.prototype,'pageY',{configurable:!0,get:function(){return this.clientY}});f.onNativeMouseEvent=function(g,h,i)"
49 | + "{try{var j=screen.logicalXDPI/screen.deviceXDPI,k=screen.logicalYDPI/screen.deviceYDPI,b=a.createEvent('MouseEvents'),c=a.body.scrollLeft+Math.round(j*h),d=a.body.scrollTop+Math.round(k*i),e=a.elementFromPoint(c,d);b.initMouseEvent(g,!0,!0,"
50 | + "f,1,c,d,c,d,!1,!1,!1,!1,0,e);return(e?!e.dispatchEvent(b):!a.dispatchEvent(b))?'true':'false'}catch(l){return l}}})(window,document);";
51 |
52 |
53 | private WebBrowser _browser;
54 |
55 | ///
56 | /// Gets or sets whether to suppress the scrolling of
57 | /// the WebBrowser control;
58 | ///
59 | public bool ScrollDisabled { get; set; }
60 |
61 | private bool userScalable = true;
62 | private double maxScale = 2.0;
63 | private double minScale = 0.5;
64 | protected Border border;
65 | private bool firstMouseMove = false;
66 |
67 |
68 | public BrowserMouseHelper(ref WebBrowser browser)
69 | {
70 | _browser = browser;
71 | browser.Loaded += new RoutedEventHandler(browser_Loaded);
72 | }
73 |
74 | private void browser_Loaded(object sender, RoutedEventArgs e)
75 | {
76 | var border0 = VisualTreeHelper.GetChild(_browser, 0);
77 | var border1 = VisualTreeHelper.GetChild(border0, 0);
78 | var panZoom = VisualTreeHelper.GetChild(border1, 0);
79 | var grid = VisualTreeHelper.GetChild(panZoom, 0);
80 | border = VisualTreeHelper.GetChild(grid, 0) as Border;
81 |
82 | if (border != null)
83 | {
84 | border.ManipulationStarted += Border_ManipulationStarted;
85 | border.ManipulationDelta += Border_ManipulationDelta;
86 | border.ManipulationCompleted += Border_ManipulationCompleted;
87 | border.DoubleTap += Border_DoubleTap;
88 | border.Hold += Border_Hold;
89 | border.MouseLeftButtonDown += Border_MouseLeftButtonDown;
90 | }
91 |
92 | _browser.LoadCompleted += Browser_LoadCompleted;
93 | }
94 |
95 | void ParseViewportMeta()
96 | {
97 | string metaScript = "(function() { return document.querySelector('meta[name=viewport]').content; })()";
98 |
99 | try
100 | {
101 | string metaContent = _browser.InvokeScript("eval", new string[] { metaScript }) as string;
102 | string[] arr = metaContent.Split(new[] { ' ', ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
103 | Dictionary metaDictionary = new Dictionary();
104 | foreach (string val in arr)
105 | {
106 | string[] keyVal = val.Split('=');
107 | metaDictionary.Add(keyVal[0], keyVal[1]);
108 | }
109 |
110 | this.userScalable = false; // reset to default
111 | if (metaDictionary.ContainsKey("user-scalable"))
112 | {
113 | this.userScalable = metaDictionary["user-scalable"] == "yes";
114 | }
115 |
116 | this.maxScale = 1.0;// reset to default
117 | if (metaDictionary.ContainsKey("maximum-scale"))
118 | {
119 | this.maxScale = double.Parse(metaDictionary["maximum-scale"]);
120 | }
121 |
122 | this.minScale = 1.0;// reset to default
123 | if (metaDictionary.ContainsKey("minimum-scale"))
124 | {
125 | this.minScale = double.Parse(metaDictionary["minimum-scale"]);
126 | }
127 | }
128 | catch (Exception)
129 | {
130 |
131 | }
132 | }
133 |
134 | void Browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
135 | {
136 | ParseViewportMeta();
137 |
138 | try
139 | {
140 | _browser.InvokeScript("execScript", MinifiedMouseScript);
141 | }
142 | catch (Exception)
143 | {
144 | Debug.WriteLine("BrowserHelper Failed to install mouse script in WebBrowser");
145 | }
146 | }
147 |
148 | bool InvokeSimulatedMouseEvent(string eventName, Point pos)
149 | {
150 | bool bCancelled = false;
151 | try
152 | {
153 | System.Diagnostics.Debug.WriteLine("Simulating " + eventName + " to position: " + pos.ToString());
154 |
155 | string strCancelled = _browser.InvokeScript("onNativeMouseEvent", new string[] { eventName, pos.X.ToString(), pos.Y.ToString() }) as string;
156 | if (bool.TryParse(strCancelled, out bCancelled))
157 | {
158 | return bCancelled;
159 | }
160 | }
161 | catch (Exception)
162 | {
163 | // script error
164 | }
165 |
166 | return bCancelled;
167 | }
168 |
169 | #region Hold
170 |
171 | void Border_Hold(object sender, GestureEventArgs e)
172 | {
173 | e.Handled = true;
174 | }
175 |
176 | #endregion
177 |
178 | #region DoubleTap
179 |
180 | void Border_DoubleTap(object sender, GestureEventArgs e)
181 | {
182 | e.Handled = true;
183 | }
184 |
185 | #endregion
186 |
187 | #region MouseEvents
188 |
189 | void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
190 | {
191 | border.MouseMove += new MouseEventHandler(Border_MouseMove);
192 | border.MouseLeftButtonUp += new MouseButtonEventHandler(Border_MouseLeftButtonUp);
193 |
194 | firstMouseMove = true;
195 |
196 | Point pos = e.GetPosition(_browser);
197 | InvokeSimulatedMouseEvent("mousedown", pos);
198 | }
199 |
200 | void Border_MouseMove(object sender, MouseEventArgs e)
201 | {
202 | Point pos = e.GetPosition(_browser);
203 | bool retVal = InvokeSimulatedMouseEvent("mousemove", pos);
204 |
205 | // only the return value from the first mouse move event should be used to determine if scrolling is prevented.
206 | if (firstMouseMove)
207 | {
208 | //ScrollDisabled = retVal;
209 | }
210 | }
211 |
212 | void Border_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
213 | {
214 | border.MouseMove -= new MouseEventHandler(Border_MouseMove);
215 | border.MouseLeftButtonUp -= new MouseButtonEventHandler(Border_MouseLeftButtonUp);
216 | Point pos = e.GetPosition(_browser);
217 | e.Handled = InvokeSimulatedMouseEvent("mouseup", pos);
218 | //ScrollDisabled = false;
219 | }
220 |
221 |
222 | #endregion
223 |
224 | #region ManipulationEvents
225 |
226 | void Border_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
227 | {
228 | if (ScrollDisabled)
229 | {
230 | e.Handled = true;
231 | e.Complete();
232 | }
233 | }
234 |
235 | private void Border_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
236 | {
237 | // optionally suppress zoom
238 | if ((ScrollDisabled || !userScalable) && (e.DeltaManipulation.Scale.X != 0.0 || e.DeltaManipulation.Scale.Y != 0.0))
239 | {
240 | e.Handled = true;
241 | e.Complete();
242 | }
243 | // optionally suppress scrolling
244 | if (ScrollDisabled && (e.DeltaManipulation.Translation.X != 0.0 || e.DeltaManipulation.Translation.Y != 0.0))
245 | {
246 | e.Handled = true;
247 | e.Complete();
248 | }
249 | }
250 |
251 | private void Border_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
252 | {
253 | // suppress zoom
254 | if (!userScalable && e.FinalVelocities != null)
255 | {
256 | if (e.FinalVelocities.ExpansionVelocity.X != 0.0 ||
257 | e.FinalVelocities.ExpansionVelocity.Y != 0.0)
258 | {
259 | e.Handled = true;
260 | }
261 | }
262 | }
263 |
264 | #endregion
265 | }
266 | }
267 |
--------------------------------------------------------------------------------
/src/Protractor/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/Protractor/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Windows;
6 | using System.Windows.Controls;
7 | using System.Windows.Documents;
8 | using System.Windows.Input;
9 | using System.Windows.Media;
10 | using System.Windows.Media.Animation;
11 | using System.Windows.Shapes;
12 | using Microsoft.Phone.Controls;
13 | using System.IO;
14 | using System.IO.IsolatedStorage;
15 | using System.Windows.Resources;
16 | using System.ComponentModel;
17 |
18 |
19 | namespace Protractor_WP
20 | {
21 | public partial class MainPage : PhoneApplicationPage
22 | {
23 | protected BrowserMouseHelper m_helper;
24 | protected IsolatedStorageSettings m_settings = IsolatedStorageSettings.ApplicationSettings;
25 |
26 | protected const string MEASURED_LENGTH_KEY = "measuredLength";
27 | protected const string MEASURED_ANLGE_RADIANS_KEY = "measuredAngleRadians";
28 | protected const string SCREEN_WIDTH_MM = "screenWidthMM";
29 | protected const string USE_MM = "useMM";
30 |
31 | // Constructor
32 | public MainPage()
33 | {
34 | InitializeComponent();
35 |
36 | m_helper = new BrowserMouseHelper(ref webBrowser);
37 | m_helper.ScrollDisabled = true;
38 |
39 | SaveFilesToIsoStore();
40 |
41 | webBrowser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(webBrowser_LoadCompleted);
42 | }
43 |
44 | ///
45 | /// Loads the stored values from the isolated storage and sets them to the HTML5 UI.
46 | ///
47 | ///
48 | ///
49 | void webBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
50 | {
51 | string measuredLength = "-1";
52 | string measuredAngleRadians = "-1";
53 | string screenWidthMM = "81"; // Default for Lumia 800
54 | string useMM = "true";
55 |
56 | if (m_settings.Contains(MEASURED_LENGTH_KEY))
57 | {
58 | measuredLength = (string)m_settings[MEASURED_LENGTH_KEY];
59 | }
60 |
61 | if (m_settings.Contains(MEASURED_ANLGE_RADIANS_KEY))
62 | {
63 | measuredAngleRadians = (string)m_settings[MEASURED_ANLGE_RADIANS_KEY];
64 | }
65 |
66 | if (m_settings.Contains(SCREEN_WIDTH_MM))
67 | {
68 | screenWidthMM = (string)m_settings[SCREEN_WIDTH_MM];
69 | }
70 |
71 | if (m_settings.Contains(USE_MM))
72 | {
73 | useMM = (string)m_settings[USE_MM];
74 | }
75 |
76 | webBrowser.InvokeScript("eval", string.Format("measuredLength = {0};", measuredLength));
77 | webBrowser.InvokeScript("eval", string.Format("measuredAngleRadians = {0};", measuredAngleRadians));
78 | webBrowser.InvokeScript("eval", string.Format("screenWidthMM = {0};", screenWidthMM));
79 | webBrowser.InvokeScript("eval", string.Format("useMM = {0};", useMM));
80 | webBrowser.InvokeScript("eval", "init();");
81 | }
82 |
83 | ///
84 | /// Called when the main page is shown. Navigates the webbrowser to the local HTML page.
85 | ///
86 | ///
87 | protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
88 | {
89 | webBrowser.Navigate(new Uri("html\\index.html", UriKind.Relative));
90 | }
91 |
92 | ///
93 | /// Called when the main page is navigated away, basically when the application is sent to background or the application is closed.
94 | /// Gets the some variables from the JavaScript to store the state of the application into the isolated storage.
95 | ///
96 | ///
97 | protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
98 | {
99 | string measuredLength = webBrowser.InvokeScript("eval", "var value = measuredLength; value.toString();") as string;
100 | string measuredAngleRadians = webBrowser.InvokeScript("eval", "var value = measuredAngleRadians; value.toString();") as string;
101 | string screenWidthMM = webBrowser.InvokeScript("eval", "var value = screenWidthMM; value.toString();") as string;
102 | string useMM = webBrowser.InvokeScript("eval", "var value = useMM; value.toString();") as string;
103 |
104 | m_settings[MEASURED_LENGTH_KEY] = measuredLength;
105 | m_settings[MEASURED_ANLGE_RADIANS_KEY] = measuredAngleRadians;
106 | m_settings[SCREEN_WIDTH_MM] = screenWidthMM;
107 | m_settings[USE_MM] = useMM;
108 | }
109 |
110 | ///
111 | /// Handles back key press. If the HTML5 UI is on config screen the back key will close it.
112 | ///
113 | ///
114 | protected override void OnBackKeyPress(CancelEventArgs e)
115 | {
116 | string inConfig = webBrowser.InvokeScript("eval", "var value = inConfig; value.toString();") as string;
117 | if (inConfig == "true")
118 | {
119 | webBrowser.InvokeScript("eval", "inConfig = false;");
120 | webBrowser.InvokeScript("eval", "draw();");
121 | e.Cancel = true;
122 | }
123 | }
124 |
125 |
126 | ///
127 | /// Saves the HTML files to isolated storage as files in order them to be viewer by the webbrowser component.
128 | ///
129 | private void SaveFilesToIsoStore()
130 | {
131 | // These files must match what is included in the application package,
132 | // or BinaryStream.Dispose below will throw an exception.
133 | string[] files = {
134 | "html/index.html",
135 | "html/script.js",
136 | "html/style.css",
137 | "html/papergrid.png",
138 | "html/settings.png"
139 | };
140 |
141 | IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
142 |
143 | foreach (string f in files)
144 | {
145 | StreamResourceInfo sr = Application.GetResourceStream(new Uri(f, UriKind.Relative));
146 | using (BinaryReader br = new BinaryReader(sr.Stream))
147 | {
148 | byte[] data = br.ReadBytes((int)sr.Stream.Length);
149 | SaveToIsoStore(f, data);
150 | }
151 | }
152 | }
153 |
154 | ///
155 | /// Saves a single file to the isolated storage.
156 | ///
157 | ///
158 | ///
159 | private void SaveToIsoStore(string fileName, byte[] data)
160 | {
161 | string strBaseDir = string.Empty;
162 | string delimStr = "/";
163 | char[] delimiter = delimStr.ToCharArray();
164 | string[] dirsPath = fileName.Split(delimiter);
165 |
166 | // Get the IsoStore.
167 | IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
168 |
169 | // Re-create the directory structure.
170 | for (int i = 0; i < dirsPath.Length - 1; i++)
171 | {
172 | strBaseDir = System.IO.Path.Combine(strBaseDir, dirsPath[i]);
173 | isoStore.CreateDirectory(strBaseDir);
174 | }
175 |
176 | // Remove the existing file.
177 | if (isoStore.FileExists(fileName))
178 | {
179 | isoStore.DeleteFile(fileName);
180 | }
181 |
182 | // Write the file.
183 | using (BinaryWriter bw = new BinaryWriter(isoStore.CreateFile(fileName)))
184 | {
185 | bw.Write(data);
186 | bw.Close();
187 | }
188 | }
189 | }
190 | }
--------------------------------------------------------------------------------
/src/Protractor/Properties/AppManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/Protractor/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 | using System.Resources;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("Protractor")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("Microsoft")]
13 | [assembly: AssemblyProduct("Protractor")]
14 | [assembly: AssemblyCopyright("Copyright © Microsoft 2012")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 | [assembly: ComVisible(false)]
22 |
23 | // The following GUID is for the ID of the typelib if this project is exposed to COM
24 | [assembly: Guid("4510ac17-3a46-473b-acf0-4f0ac31f57b2")]
25 |
26 | // Version information for an assembly consists of the following four values:
27 | //
28 | // Major Version
29 | // Minor Version
30 | // Build Number
31 | // Revision
32 | //
33 | // You can specify all the values or you can default the Revision and Build Numbers
34 | // by using the '*' as shown below:
35 | [assembly: AssemblyVersion("1.1.0")]
36 | [assembly: AssemblyFileVersion("1.1.0")]
37 | [assembly: NeutralResourcesLanguageAttribute("en-US")]
38 |
--------------------------------------------------------------------------------
/src/Protractor/Properties/WMAppManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ApplicationIcon.png
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | Background.png
29 | 0
30 | Protractor
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/Protractor/Protractor.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 10.0.20506
7 | 2.0
8 | {580079E8-E581-4310-869D-A0924A5BBEB0}
9 | {C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
10 | Library
11 | Properties
12 | Protractor_WP
13 | Protractor-WP
14 | v4.0
15 | $(TargetFrameworkVersion)
16 | WindowsPhone71
17 | Silverlight
18 | true
19 |
20 |
21 | true
22 | true
23 | Protractor.xap
24 | Properties\AppManifest.xml
25 | Protractor_WP.App
26 | true
27 | true
28 |
29 |
30 | true
31 | full
32 | false
33 | Bin\Debug
34 | DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE
35 | true
36 | true
37 | prompt
38 | 4
39 |
40 |
41 | pdbonly
42 | true
43 | Bin\Release
44 | TRACE;SILVERLIGHT;WINDOWS_PHONE
45 | true
46 | true
47 | prompt
48 | 4
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | App.xaml
63 |
64 |
65 |
66 | MainPage.xaml
67 |
68 |
69 |
70 |
71 |
72 | Designer
73 | MSBuild:Compile
74 |
75 |
76 | Designer
77 | MSBuild:Compile
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | PreserveNewest
87 |
88 |
89 | PreserveNewest
90 |
91 |
92 | Designer
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
109 |
110 |
--------------------------------------------------------------------------------
/src/Protractor/SplashScreenImage.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/src/Protractor/SplashScreenImage.jpg
--------------------------------------------------------------------------------
/src/Protractor/html/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Protractor
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/Protractor/html/papergrid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/src/Protractor/html/papergrid.png
--------------------------------------------------------------------------------
/src/Protractor/html/script.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/src/Protractor/html/script.js
--------------------------------------------------------------------------------
/src/Protractor/html/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/src/Protractor/html/settings.png
--------------------------------------------------------------------------------
/src/Protractor/html/style.css:
--------------------------------------------------------------------------------
1 | #canvas {
2 | position: absolute;
3 | }
4 |
5 | #dpi {
6 | position: absolute;
7 | width: 1in;
8 | height: 1in;
9 | top: -100%;
10 | left: -100%;
11 | }
--------------------------------------------------------------------------------
/src/Protractor/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Protractor
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/Protractor/script.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/protractor/45a57256f7ae7c342bcb4a5abd051282ff9d3a8b/src/Protractor/script.js
--------------------------------------------------------------------------------
/src/Protractor/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | width: 100%;
4 | height: 100%;
5 | position: absolute;
6 | }
7 |
8 | #canvas {
9 | position: absolute;
10 | }
11 |
12 | #dpi {
13 | position: absolute;
14 | width: 1in;
15 | height: 1in;
16 | top: -100%;
17 | left: -100%;
18 | }
--------------------------------------------------------------------------------