speedometer-icon

Technorati Tags: Speedometer,Winodws Phone 7,development

Creating a speedometer ,largely depends whether you want to display a numerical readout, or as a rotating needle.

First, to get the actual speed value, as mentioned in another answer, you can simply use the rigid body’s velocity. However, Unity’s default scale is one unit = one meter, so reading rigidbody.velocity.magnitude will give you the speed in meters per second.

To convert to MPH, you can use:

 1: var mph = rigidbody.velocity.magnitude * 2.237;

Convert to KPH:

 1: var kph = rigidbody.velocity.magnitude * 3.6;

Next to display it.

To show the speed as a numerical readout is comparitively simple:

1) Create a GUIText gameobject (from the gameobject menu).

2) In your car script, create a var which will store a reference to this GUIText GameObject:

 

 1: var mphDisplay : GUIText;

3) Select your car, and drag a reference from the new GUIText GameObject in the hierarchy into this variable slot in car script, in the inspector.

4) Now, in your car script, you can add the lines in your Update() function to calculate the MPH, and update the text displayed:

 1: var mph = rigidbody.velocity.magnitude * 2.237;
 2: mphDisplay.text = mph + " MPH";

That should get you working with a numerical readout.

 

To display as a rotating needle requires some trickier coordination. There’s no simple way to rotate a GUI Texture, or a texture drawn using the OnGUI method, so I’ve written a small general-purpose script which you can place on a gameobject to create a rotatable GUI Texture. You can control it by setting the ‘angle’ variable from other scripts.

So:

1) Create a new C# script. Name it “RotatableGuiItem”, and paste in this script:

 1: using UnityEngine;
 2: [ExecuteInEditMode()]
 3: public class RotatableGuiItem : MonoBehaviour {
 4: 
 5:     public Texture2D texture = null;
 6:     public float angle = 0;
 7:     public Vector2 size = new Vector2(128, 128);
 8:     Vector2 pos = new Vector2(0, 0);
 9:     Rect rect;
 10:     Vector2 pivot;
 11: 
 12:     void Start() {
 13:         UpdateSettings();
 14:     }
 15: 
 16:     void UpdateSettings() {
 17:         pos = new Vector2(transform.localPosition.x, transform.localPosition.y);
 18:         rect = new Rect(pos.x - size.x * 0.5f, pos.y - size.y * 0.5f, size.x, size.y);
 19:         pivot = new Vector2(rect.xMin + rect.width * 0.5f, rect.yMin + rect.height * 0.5f);
 20:     }
 21: 
 22:     void OnGUI() {
 23:         if (Application.isEditor) { UpdateSettings(); }
 24:         Matrix4x4 matrixBackup = GUI.matrix;
 25:         GUIUtility.RotateAroundPivot(angle, pivot);
 26:         GUI.DrawTexture(rect, texture);
 27:         GUI.matrix = matrixBackup;
 28:     }
 29: }

 

3) Create a new empty GameObject. Name it “mph needle”. Add the RotatableGuiItem script to it.

4) Assign your speedo needle “Texture” variable. You probably want to use a texture with a transparent alpha background for this, and bear in mind that it will rotate around the centre of the image. Adjust the “size” values to match the size of your texture.

5) Adjust the position of the texture using the X and Y position values of the GameObject in the inspector, so that it is your desired position. (probably in the centre of a normal static GUI Texture showing the mph dial face).

6) In your car script, create a var which will store a reference to this rotatable GUI item:

 1: var mphNeedle : RotatableGuiItem;

7) Select your car, and drag a reference from the “mph needle” GameObject in the hierarchy into this variable slot in car script, in the inspector.

8) Now, in your car script, you can add the lines in your Update() function to calculate the MPH, and update the needle’s angle:

 1: var mph = rigidbody.velocity.magnitude * 2.237;
 2: mphNeedle.angle = mph;

You will probably need to adjust how far the needle turns in relation to the mph, and at what angle it starts, so you may end up with a line which looks more like this:

 1: mphNeedle.angle = 20 + mph * 1.4f;

 

Which means the needle will be rotated by 20 degrees when the mph is zero, and will rotate 1.4 degrees for every 1 mph.

(If you want to control this script from a Javascript script, you’ll have to move the C# RotatableGuiItem into a folder called PlugIns in your assets.)

Hopefully this should get you to the stage where you have a working speedometer with a rotating needle!

 

Please comment, I have worked hours solving this, if you comment, it will give me some support!Laughing out loud

I saw a question on stackoverflow.com about theme management in a Silverlight application. As I stated in my answer, there’s no specific API to manage a theme like you know it in Windows. However you have the concept of ResourceDictionnary. Yesterday I posted a link to a video from Microsoft showing different applications with very different “themes”. So you have some liberties from the minimalist UI of Windows Phone 7. But how can you change the default color while still following the guidelines of Microsoft? You can modify the styles provided in the SDK. In the folder “C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.0\Design” you will find several XAML files:

ThemeResource.xaml contains the basic Color, SolidColorBrush and TextBlock resources. You can copy/paste this file in your application and reference it in the App.xaml to override specific styles.

System.Windows.xaml has the styles for controls like Button, CheckBox, etc. Again you can use it to override the look and feel of the widgets.

Finally, there is one folder for each of the 10 “accent” colors (blue is the default) for both the light and dark themes (the operator can provide a 11th color).

 

This is a sample with the default dark theme :

1    <Application.Resources>
2    <ResourceDictionary>
3        <ResourceDictionary.MergedDictionaries>
4            <ResourceDictionary Source="Resources/Styles.xaml"/>
5                   </ResourceDictionary.MergedDictionaries>
6    </ResourceDictionary>
7    </Application.Resources>

In the Styles.xaml file you have a copy of the content of ThemeResource.xaml file from the SDK :

1    <ResourceDictionary
2      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4      xmlns:System="clr-namespace:System;assembly=mscorlib">
5
6     <Color x:Key="PhoneForegroundColor">#000000</Color>
7     <Color x:Key="PhoneBackgroundColor">#D2D9AE</Color>
8    (...)
9    </ResourceDictionary>

 

And now the look and feel of your application is customized.

One important notice: even though if you can override all the controls’ styles you should keep an eye on the implicit contract imposed by the platform i.e. the “Metro” UI guidelines. For example, it’s probably a bad idea to change the appearance of the default Button because your users will look after a particular widget in the page to save, confirm, send, etc.

Please Feelo Free To contact me and please do comment, I need them for sure.

Creating File Uploader For Window Phone 7

This is very basic level small user control, in which we can discuss how to create web user control.

To create user controls follow the steps:

  1. Right click on project
  2. Click on Add
  3. Select New Item
  4. Select Web User Control
  5. Specify some Name

I have given name to this file as “uploader.ascx” and kept this file under “userControl” for simplicity purpose.

On this page I am having following controls:

 

 1:     <INPUT id="fileUpload" type="file" Runat="server" NAME="fileUpload">
 2: 
 3:     <asp:label id="lblMessage" runat="server" Width="416px" Font-Size="10" Font-Name="verdana"></asp:label>
 4: 
 5:     <asp:button id="btnSave" runat="server" Text="Upload.."></asp:button>
 6: 
 7: At the code behind of above file I am having following function
 8: 
 9: public string uploadFile(string fileName,string folderName)
 10: 
 11: {
 12: 
 13:           if(fileName=="")
 14: 
 15:           {
 16: 
 17:                     return "Invalid filename supplied";
 18: 
 19:           }
 20: 
 21:           if(fileUpload.PostedFile.ContentLength==0)
 22: 
 23:           {
 24: 
 25:                     return "Invalid file content";
 26: 
 27:           }
 28: 
 29:                     fileName = System.IO.Path.GetFileName(fileName);
 30: 
 31:           if(folderName=="")
 32: 
 33:                     {
 34: 
 35:                     return "Path not found";
 36: 
 37:                     }
 38: 
 39:                     try
 40: 
 41:                     {
 42: 
 43:                     if (fileUpload.PostedFile.ContentLength<=2048000)
 44: 
 45:                               {
 46: 
 47:           fileUpload.PostedFile.SaveAs(Server.MapPath(folderName)+"\\"+fileName); 
 48: 
 49:                                        return "File uploaded successfully"; 
 50: 
 51:                              }
 52: 
 53:                              else
 54: 
 55:                     {
 56: 
 57:                               return "Unable to upload,file exceeds maximum limit";
 58: 
 59:                              }
 60: 
 61:           }
 62: 
 63:                     catch(UnauthorizedAccessException ex)
 64: 
 65:                     {
 66: 
 67:                     return ex.Message + "Permission to upload file denied";
 68: 
 69:                     }
 70: 
 71: }

 

The above function takes care of following things before uploading file to the folder

  1. Invalid file name supplied.
  2. If file not exists or content length 0.
  3. Folder name exists.

 

Error Handling

 

While uploading done with UnauthorizedAccessException and returned with the message

On upload button click I am having following code

 

 1: private void btnSave_Click(object sender, System.EventArgs e)
 2: 
 3: {
 4: 
 5:           string strFilename, strMessage;
 6: 
 7:           strFilename = fileUpload.PostedFile.FileName.ToString();
 8: 
 9:           strMessage = uploadFile(strFilename,ConfigurationSettings.AppSettings["folderPath"]);
 10: 
 11:           lblMessage.Text = strMessage;
 12: 
 13:           lblMessage.ForeColor = Color.Red;
 14: 
 15: }
 16: 
 17: I have made use of Web.config file, in which I have added attribute as follows under:
 18: 
 19: <configuration>
 20:       <appSettings>
 21:          <add key="folderPath" value="Images"></add>
 22:       </appSettings>

 

i.e. I have set up path of folder to upload image

To access control in project, I have added page called as “uploadTester.aspx” to the project in which I have added following line:

<%@ Register TagPrefix=”img” TagName=”Uploader” src=”userControl/uploader.ascx”%>

Which says that this control is register to this page with specified source.

And in HTML code I have added following code inside form tag:

<img:Uploader runat=”server” id=”Uploader1″></img:Uploader>

That’s all about

 

General:

To upload any of the file in respective folder user need to have permission for writing to the folder so please follow the following steps to prevent from the error.

Set permission to virtual directory by following steps in IIS

  • Right Click on virtual directory which you have created for this project. Under directory Tab you will find
    1)Read
    2)Log Visits
    3)Index this resources
    Are marked as checked (enables) in addition to this make
    4)Write access enabled or checked
  • Click on apply
  • Click on ok

This will set right permission to entire virtual directory, this way we can minimize error from the front end for permission / access denied.

Other way to solve permission denied issue is to go to actual folder “images” by using physical path and follow these steps:

  • Right click folder
  • Sharing Tab
  • Enable share this folder radio button
  • Click Apply
  • Click Ok

If u are using this code on 2000 server you should do following:

  • Right click respective folder
  • Go to security tab
  • Select Everyone user
  • Apply full control
  • click on ok

 

Please Do comment!

  • Click on Add
  • Select New Item
  • Select Web User Control
  • Specify some Name

I have given name to this file as “uploader.ascx” and kept this file un

Creating a Simple Download Manager For Window Phone 7

Start by creating a C# Windows Application project in Visual Studio and on the form drag 3 labels, 2 textboxes, 2 buttons and one progressbar.

As you can see in the form above, the first two labels are just for describing the role of the first two textboxes which are named txtUrl and txtPath. They will obviously hold the URL of the file we want to download and the local path (and filename) to where we want to save it. The default values I set in the project will download a short video from Microsoft’s Channel 9 website to C:\Filename.wmv.
The two buttons – btnDownload and btnStop – are used for starting and stopping a download, while the label below them – lblProgress – is used for showing the current progress of the download in bytes and percentage. Finally, the ProgressBar located at the bottom of the form is entitled prgDownload and it display the progress of the download on a scale from 1 to 100.

Now let’s get into coding. Switch to code view, and the first thing we need to do is to add a few using statements for the namespaces we’re going to use. Add the following 3 lines below the already existing using statements:

 1: using System.Net;
 2: using System.IO;
 3: using System.Threading;

 

 

System.Net will be used for connecting to the web server, System.IO will be used for saving the file to the hard drive, and System.Threading will be used for the thread in which we’re going to put the downloading process.

Inside the form’s class, right above the constructor, add the following lines:

 1: // The thread inside which the download happens
 2: private Thread thrDownload;
 3: // The stream of data retrieved from the web server
 4: private Stream strResponse;
 5: // The stream of data that we write to the harddrive
 6: private Stream strLocal;
 7: // The request to the web server for file information
 8: private HttpWebRequest webRequest;
 9: // The response from the web server containing information about the file
 10: private HttpWebResponse webResponse;
 11: // The progress of the download i ain percentage
 12: private static int PercentProgress;
 13: // The delegate which we will call from the thread to update the form
 14: private delegate void UpdateProgessCallback(Int64 BytesRead, Int64 TotalBytes);

 

 

As you can see, we are creating a few objects that we’re going to use later in the code. The object that stands out the most is not really an object, but a delegate: UpdateProgressCallback – this delegate will be used to call a method you’ll see later in our code – UpdateProgress – from inside the thread. Because you see, from inside a thread we can’t update the form elements directly (the label and the progress bar), so we need to create a delegate first, that takes the same arguments as the method. In our case the arguments are two Int64 variables that hold the number of bytes we downloaded from the server by now, and the number of total bytes the file has. Int64 is needed because this number can be really big.

Now let’s review the biggest piece of the code. The one where the file actually gets downloaded. We’ll put this code in a method called Download() which we’re going to call in a thread when the download button is pressed. Here goes the method, below it there’s more explanation of the code:

 1: private void Download()
 2: {
 3: using (WebClient wcDownload = new WebClient())
 4: {
 5: try
 6: {
 7: // Create a request to the file we are downloading
 8: webRequest = (HttpWebRequest)WebRequest.Create(txtUrl.Text);
 9: // Set default authentication for retrieving the file
 10: webRequest.Credentials = CredentialCache.DefaultCredentials;
 11: // Retrieve the response from the server
 12: webResponse = (HttpWebResponse)webRequest.GetResponse();
 13: // Ask the server for the file size and store it
 14: Int64 fileSize = webResponse.ContentLength;
 15: 
 16: // Open the URL for download 
 17: strResponse = wcDownload.OpenRead(txtUrl.Text);
 18: // Create a new file stream where we will be saving the data (local drive)
 19: strLocal = new FileStream(txtPath.Text, FileMode.Create, FileAccess.Write, FileShare.None);
 20: 
 21: // It will store the current number of bytes we retrieved from the server
 22: int bytesSize = 0;
 23: // A buffer for storing and writing the data retrieved from the server
 24: byte[] downBuffer = new byte[2048];
 25: 
 26: // Loop through the buffer until the buffer is empty
 27: while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
 28: {
 29: // Write the data from the buffer to the local hard drive
 30: strLocal.Write(downBuffer, 0, bytesSize);
 31: // Invoke the method that updates the form's label and progress bar
 32:             this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { strLocal.Length, fileSize });
 33: }
 34: }
 35: finally
 36: {
 37: // When the above code has ended, close the streams
 38: strResponse.Close();
 39: strLocal.Close();
 40: }
 41: }
 42: }
 43: 

 

The first line inside the method mentions that inside this method we’ll be using the wcDownload object, which can be disposed after we’re finished. If any error happens within the code, we have a finally block which closes the streams to prevent keeping a connection opened uselessly and to prevent the local file from being locked by the code.

Inside the try block we first retrieve information about the file using HttpWebRequest and HttpWebResponse objects. Note that some servers don’t give information about the size of the file, case in which we can only download blindly. If the web server did not return any information regarding the size of the file, webResponse.ContentLength will return -1.

After we get the size of the file, we define the stream that retrieves the bytes from the server, and the stream that saves the file to the hard drive. Before starting to stream the bytes down the cables, we create a buffer where we store the data that is written to the hard drive file. The buffer is 2048 bytes in size, but you can change it to a different value if you prefer.

In the while loop we loop through the buffer and write the content of the buffer to the file on the local drive. We also use the Invoke method of the form to call UpdateProgressCallback (the delegate of UpdateProgress). In the array we pass two parameters that UpdateProgress accepts: how much we downloaded until now (by measuring the length of the local stream), and how big the total file is. If you don’t have any knowledge of threading in C#, you probably would have guessed that you can update the form elements (labels, progress bars, etc.) directly, but for good enough reasons you can’t.
If we were to call the Download() method directly, then we wouldn’t have to use this.Invoke to call the UpdateProgress method. Speaking of UpdateProgress, let’s see how this method looks like:

 1: private void UpdateProgress(Int64 BytesRead, Int64 TotalBytes)
 2: {
 3: // Calculate the download progress in percentages
 4: PercentProgress = Convert.ToInt32((BytesRead * 100) / TotalBytes);
 5: // Make progress on the progress bar
 6: prgDownload.Value = PercentProgress;
 7: // Display the current progress on the form
 8: lblProgress.Text = "Downloaded " + BytesRead + " out of " + TotalBytes + " (" + PercentProgress + "%)";
 9: }

 

We do a simple math calculation to get the percentage (0 to 100) and we set it on the ProgressBar to reflect the progress. We also set the label with information on the progress of the download.

We’re done with the methods for this application, now we only need to create the two event handlers for the Download and Stop buttons. Double clicking btnDownload in Visual Studio 2005 will create the Click event handler for you. Use the following code:

 1: private void btnDownload_Click(object sender, EventArgs e)
 2: {
 3: // Let the user know we are connecting to the server
 4: lblProgress.Text = "Download Starting";
 5: // Create a new thread that calls the Download() method
 6: thrDownload = new Thread(Download);
 7: // Start the thread, and thus call Download()
 8: thrDownload.Start();
 9: }

 

In the code above we start a new thread, to which we pass the name of the method (without the parenthesis). Then we start the thread. The reason we need to use a thread and we can’t just call the method from inside the Click event is because in that case our application would completely hang while downloading the file. It would become unusable and unresponsive, as if it crashed.

Finally, we have the code for the stop button:

 1: private void btnStop_Click(object sender, EventArgs e)
 2: {
 3: // Close the web response and the streams
 4: webResponse.Close();
 5: strResponse.Close();
 6: strLocal.Close();
 7: // Abort the thread that's downloading
 8: thrDownload.Abort();
 9: // Set the progress bar back to 0 and the label
 10: prgDownload.Value = 0;
 11: lblProgress.Text = "Download Stopped";
 12: }

 

To make this a real download manager, we’d have to add resume options, and a download list so that we give the user the option to download multiple files at once, or schedule them. This will be covered in a future tutorial.

Below is the entire source code of Form1.csthat you can also view in the Visual Studio 2005 project files attached to this tutorial.

 1: using System;
 2: using System.Collections.Generic;
 3: using System.ComponentModel;
 4: using System.Data;
 5: using System.Drawing;
 6: using System.Text;
 7: using System.Windows.Forms;
 8: using System.Net;
 9: using System.IO;
 10: using System.Threading;
 11: 
 12: namespace DownloadManager
 13: {
 14:    public partial class Form1 : Form
 15: {
 16: // The thread inside which the download happens
 17: private Thread thrDownload;
 18: // The stream of data retrieved from the web server
 19: private Stream strResponse;
 20: // The stream of data that we write to the harddrive
 21: private Stream strLocal;
 22: // The request to the web server for file information
 23: private HttpWebRequest webRequest;
 24: // The response from the web server containing information about the file
 25: private HttpWebResponse webResponse;
 26: // The progress of the download in percentage
 27: private static int PercentProgress;
 28:       // The delegate which we will call from the thread to update the form
 29: private delegate void UpdateProgessCallback(Int64 BytesRead, Int64 TotalBytes);
 30: 
 31: public Form1()
 32: {
 33: InitializeComponent();
 34: }
 35: 
 36: private void btnDownload_Click(object sender, EventArgs e)
 37: {
 38: // Let the user know we are connecting to the server
 39: lblProgress.Text = "Download Starting";
 40: // Create a new thread that calls the Download() method
 41: thrDownload = new Thread(Download);
 42: // Start the thread, and thus call Download()
 43: thrDownload.Start();
 44: }
 45: 
 46:    private void UpdateProgress(Int64 BytesRead, Int64 TotalBytes)
 47: {
 48: // Calculate the download progress in percentages
 49: PercentProgress = Convert.ToInt32((BytesRead * 100) / TotalBytes);
 50: // Make progress on the progress bar
 51: prgDownload.Value = PercentProgress;
 52: // Display the current progress on the form
 53: lblProgress.Text = "Downloaded " + BytesRead + " out of " + TotalBytes + " (" + PercentProgress + "%)";
 54: }
 55: 
 56: private void Download()
 57: {
 58:       using (WebClient wcDownload = new WebClient())
 59: {
 60: try
 61: {
 62: // Create a request to the file we are downloading
 63: webRequest = (HttpWebRequest)WebRequest.Create(txtUrl.Text);
 64: // Set default authentication for retrieving the file
 65: webRequest.Credentials = CredentialCache.DefaultCredentials;
 66: // Retrieve the response from the server
 67: webResponse = (HttpWebResponse)webRequest.GetResponse();
 68: // Ask the server for the file size and store it
 69: Int64 fileSize = webResponse.ContentLength;
 70: 
 71: // Open the URL for download 
 72: strResponse = wcDownload.OpenRead(txtUrl.Text);
 73: // Create a new file stream where we will be saving the data (local drive)
 74: strLocal = new FileStream(txtPath.Text, FileMode.Create, FileAccess.Write, FileShare.None);
 75: 
 76: // It will store the current number of bytes we retrieved from the server
 77: int bytesSize = 0;
 78: // A buffer for storing and writing the data retrieved from the server
 79: byte[] downBuffer = new byte[2048];
 80: 
 81: // Loop through the buffer until the buffer is empty
 82: while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
 83: {
 84: // Write the data from the buffer to the local hard drive
 85: strLocal.Write(downBuffer, 0, bytesSize);
 86: // Invoke the method that updates the form's label and progress bar
 87:                   this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { strLocal.Length, fileSize });
 88: }
 89: }
 90: finally
 91: {
 92: // When the above code has ended, close the streams
 93: strResponse.Close();
 94: strLocal.Close();
 95: }
 96: }
 97: }
 98: 
 99: private void btnStop_Click(object sender, EventArgs e)
 100: {
 101: // Close the web response and the streams
 102: webResponse.Close();
 103: strResponse.Close();
 104: strLocal.Close();
 105: // Abort the thread that's downloading
 106: thrDownload.Abort();
 107: // Set the progress bar back to 0 and the label
 108: prgDownload.Value = 0;
 109: lblProgress.Text = "Download Stopped";
 110: }
 111: }
 112: }
 113: 
 114: 
 115: 

Please Do comment ,if you liked my tutorial.

Alright guys i am back with a new concept in Windows Phone 7 ( WP7 ) which is ViewStateManager. It is a really important concept for understanding visual states associated with them. If you want to create different states for your custom control then we would have to use Visual State Manager.

If you have the solution from my previous post then you can continue with it or you can download the solution here.

We will a few custom states and also learn about behaviours in this post.

  •  Now open CompanyLocations.xaml in expression blend. Drag four TextBlock controls onto the design surface, two for the headers and two for the details and then lay them out similar to the following snapshot.
Location Details

Location Details

  • Lets add a little more fun to this. Add two more textblock rotated at 90 degree and move the location details of the screen and also increase the font size of the headings as in the image below.
Text Rotation

Text Rotation

  • Now let’s go to the top left of expression blend where we have states and lets create new state group. Click on the Add State Group button and name the state group as LocationStates. Now add two new states namely CorporateState and SatalliteState. Now your state group should look something loke the screenshot below:

  • Now select CorporateState to start recording for that state which you can verify by seeing the red dot at the top right of the design surface. Now this will record any changes to the state as compared to the base state. Layout the CorporateState as shown in the image below:

 

CorporateState

CorporateState

  •  Layout for the SatelliteState is shown below:
SatelliteState

SatelliteState

  • Now lets switch back to the initial state and that any changes we make will affect all the states.
  • Now lets include behavior to bind these states to action. So now in your assets window search for GoToStateAction and drag and drop it to both the CorporateOffice and SatelliteOffice text.
GoToStateAction

GoToStateAction

  •  Now change the name to the GoToStateAction to the appropriate statename.