Archive

Archive for the ‘C#’ Category

MonoTouch: Simple Web Server

August 18, 2010 Leave a comment

A web server can be a very flexible solution to transferring data from your application. MonoTouch makes it extremely easy to add a web server to your iPhone/iPad application by using the HttpListener class. You can actually implement one with just two methods.

Now this is a very simple example that will just serve up some HTML but you can start from it and extend it to whatever your needs may be. Download the solution file here.

You’ll need to declare two member variables:

private HttpListener listener;
private bool listenerRunning = false;

I used a button click event to both start and stop the server:

partial void startOrStopServer (UIButton sender)
{
	if (!listenerRunning) {
		listener = new HttpListener();
		//Add generic prefix using port 8080
		listener.Prefixes.Add("http://*:8080/");
		
		//Start the server
		listener.Start();
		txtInfo.Text += "Server Started\n";
		btnStart.SetTitle("Stop Server", UIControlState.Normal);
	
		//Begin listening for requests asynchronously
		listener.BeginGetContext(new AsyncCallback(HandleRequest), listener);
	} else {
		//Close the server
		listener.Close();
		listener = null;
		txtInfo.Text += "Server Stoped\n";
		btnStart.SetTitle("Start Server", UIControlState.Normal);
	}
	
	listenerRunning = !listenerRunning;
} 

Request handler method:

private void HandleRequest(IAsyncResult result) {
	if (!listenerRunning) return;
	
	//Get the listener context
	HttpListenerContext context = listener.EndGetContext(result);
	//Start listening for the next request
	listener.BeginGetContext(new AsyncCallback(HandleRequest), listener);
	
	//Update status on the UI thread
	InvokeOnMainThread( delegate {
		txtInfo.Text += "Received request from: " + context.Request.UserHostAddress + "\n";
	});
	
	//Here you can create any response that you want. You can serve text or a file or whatever else you need.
	string response = "<html><head><title>Sample Response</title></head><body>Response from mtouchwebserver.</body></html>";
	byte[] responseBytes = System.Text.Encoding.UTF8.GetBytes(response);
	
	//Set some response information
	context.Response.ContentType = "text/html";
	context.Response.StatusCode = (int)HttpStatusCode.OK;
	context.Response.ContentLength64 = responseBytes.Length;
	
	//Write the response.
	context.Response.OutputStream.Write(responseBytes, 0, responseBytes.Length);
	context.Response.OutputStream.Close();
}

You can run the example solution in the iPhone simulator, start the server, then open a browser and go to http://localhost:8080 to see the results.

Categories: C#, iPhone, MonoTouch Tags: , , ,

MonoTouch: Drawing Rotated Text

July 21, 2010 3 comments

Drawing Rotated Text

I’m taking a break from reading the Professional iPhone Programming with MonoTouch and .NET/C# book (which is awesome by the way) so I decided to write a little tutorial on drawing rotated text.

You can download the MonoDevelop solution here.

There are two drawing methods in the solution, one that shows you how to draw vertical text and one that shows you how to draw rotated text in a circle. Both use the CGAffineTransform object and are pretty similar, but I also show you how to measure a string’s width in the vertical text function.

Let’s take a look at the DrawRotatedText function first:

public static UIImage DrawRotatedText(string text, int width, int height) 
{
	float centerX = width / 2;
	float centerY = height / 2;
	
	//Create the graphics context
	CGBitmapContext ctx = new CGBitmapContext(IntPtr.Zero, width, height, 8, 4 * width, 
		CGColorSpace.CreateDeviceRGB(), CGImageAlphaInfo.PremultipliedFirst);
			
	//Set the font
	ctx.SelectFont("Arial", 16f, CGTextEncoding.MacRoman);	
	
	//Set the fill color to blue
	ctx.SetRGBFillColor(0f, 0f, 1f, 1f);

	//Set the drawing mode 
	ctx.SetTextDrawingMode(CGTextDrawingMode.Fill);
	
	//Draw the text every 22.5 degrees to complete a circle
	for (double angle = 22.5; angle <= 360; angle += 22.5)
	{
		ctx.TextMatrix = CGAffineTransform.MakeRotation((float)DegreesToRadians(angle));
		ctx.ShowTextAtPoint(centerX, centerY, text);
	}
	
	//Return the image
	return UIImage.FromImage(ctx.ToImage());
							 
}

If you’ve read my other MonoTouch drawing posts, you’ll see that the setup is pretty much the same. First create the drawing context, set the font, set the colors, and fill mode. The part that actually does the text rotation is line 22. You set the drawing context’s TextMatrix property equal to a CGAffineTransform object that comes from the static MakeRotation method by passing in a rotation angle in radians. The for loop simply creates a circle of text strings at the center of the image.

Now let’s look at the DrawVerticalText function:

public static UIImage DrawVerticalText(string text, int width, int height)
{
	float centerX = width / 2;
	float centerY = height / 2;
	
	//Create the graphics context
	CGBitmapContext ctx = new CGBitmapContext(IntPtr.Zero, width, height, 8, 4 * width, 
			CGColorSpace.CreateDeviceRGB(), CGImageAlphaInfo.PremultipliedFirst);
	
	//Set the font
	ctx.SelectFont("Arial", 16f, CGTextEncoding.MacRoman);
	
	//Measure the text's width - This involves drawing an invisible string to calculate the X position difference
	float start, end, textWidth;
	
	//Get the texts current position
	start = ctx.TextPosition.X; 
	//Set the drawing mode to invisible
	ctx.SetTextDrawingMode(CGTextDrawingMode.Invisible);
	//Draw the text at the current position
	ctx.ShowText(text);
	//Get the end position
	end = ctx.TextPosition.X;
	//Subtract start from end to get the text's width
	textWidth = end - start;
	
				
	//Set the fill color to blue
	ctx.SetRGBFillColor(0f, 0f, 1f, 1f);

	//Set the drawing mode back to something that will actually draw Fill for example
	ctx.SetTextDrawingMode(CGTextDrawingMode.Fill);
	
	//Set the text rotation to 90 degrees - Vertical from bottom to top.
	ctx.TextMatrix = CGAffineTransform.MakeRotation((float)DegreesToRadians(90));
	//Draw the text at the center of the image.
	ctx.ShowTextAtPoint(centerX - 5, centerY - (textWidth / 2), text);
	
	//Set the text rotation to 270 degrees - Vertical from top to bottom.
	ctx.TextMatrix = CGAffineTransform.MakeRotation((float)DegreesToRadians(270));
	//Draw the text as the center of the image.
	ctx.ShowTextAtPoint(centerX + 5, centerY + (textWidth / 2), text);
	
	//Return the image
	return UIImage.FromImage(ctx.ToImage());
}

So again this looks very similar, to get vertical text you just need to set the rotation angle to 90 degrees for bottom to top text or 270 degrees for top to bottom text.

The function will also center the text in the middle of the image. To do this you need to know what the width of the text will be. There is no Graphics.MeasureString function so you need to do it the Quartz 2d way which involves getting the current text position, setting the draw mode to invisible, drawing the string, getting the end text position, then subtracting the starting position from the end position. Now you can do some simple math to center your text something like (width / 2 – (textWidth / 2), remember to adjust your calculations when you do rotations because you won’t be dealing with just the X coordinate at that point and you may not be drawing from left to right.

Now go add some crazy rotating text to your MonoTouch apps. :-)

Categories: C#, iPhone, MonoTouch

Quick Tip: Simple HTTP Post Using Monotouch

July 19, 2010 Leave a comment

I’ve decided to start a quick tip series on this blog. I’ll try to post some useful code snippets along with some tips and tricks that I’ve learned throughout the years.

This first quick tip shows you how to do a simple HTTP Post in MonoTouch.

You can download the example solution here.

public static string HttpPost(string url, string parameters) 
{
	try
	{
		//Create a WebRequest
		WebRequest req = WebRequest.Create(url);

		//Set the content type and method
		req.ContentType = "application/x-www-form-urlencoded";
		req.Method = "POST";

		//Get the total size of the post parameters and set the content length
		byte [] bytes = System.Text.Encoding.UTF8.GetBytes(parameters);
		req.ContentLength = bytes.Length;

		//Write the data to the request stream
		Stream os = req.GetRequestStream ();
		os.Write (bytes, 0, bytes.Length); 
		os.Close ();

		//Get the response
		WebResponse resp = req.GetResponse();
		if (resp== null) return null;

		//Get the response stream and read the response
		StreamReader sr = new StreamReader(resp.GetResponseStream());			
		string result = sr.ReadToEnd().Trim();
		
		//Close the streams
		sr.Close();
		resp.Close();
		
		return result; 
	}
	catch
	{
		//Epic fail...
		return null;
	}
}

The download also includes a sample PHP page that you can use for testing the POST.

Categories: C#, iPhone, MonoTouch, Quick Tips

MonoTouch: Drawing custom progress bars.

October 16, 2009 2 comments
MonoTouch Progress Bar

MonoTouch Progress Bar

Here is a simple MonoTouch app that demonstrates how to use Quartz2D to draw custom progress bars.  You can download the MonoDevelop project here.

This app shows how to draw a simple two color progress bar using alpha transparency and a simple two color gradient progress bar.  There are sliders that let you control the colors, transparency level, and progress percentage.  The code uses the CGBitmapContext class to create an image and loads it into UIImageView.

This is the function to create a basic progress bar:

private UIImage makeProgressImage(int width, int height, float progress, CGColor baseColor, CGColor topColor)
{
   //Create a CGBitmapContext object
   CGBitmapContext ctx = new CGBitmapContext(IntPtr.Zero, width, height, 8, 4 * width, CGColorSpace.CreateDeviceRGB(), CGImageAlphaInfo.PremultipliedFirst);

   //Draw a rectangle with the base color
   ctx.SetFillColorWithColor(baseColor);
   ctx.FillRect(new RectangleF(0,0, width, height));

   //Calculate the width of the 2nd rectangle based on the progress
   float percentWidth = width * progress;

   //Draw the second rectangle with the top color
   ctx.SetFillColorWithColor(topColor);
   ctx.FillRect(new RectangleF(0, 0, percentWidth, height));

   //return a UIImage object
   return UIImage.FromImage(ctx.ToImage());
}

This is the function to create a gradient progress bar:

private UIImage makeGradientProgressImage(int width, int height, float progress, float[] components, float[] locations)
{
   //Create a CGBitmapContext object
   CGBitmapContext ctx = new CGBitmapContext(IntPtr.Zero, width, height, 8, 4 * width, CGColorSpace.CreateDeviceRGB(), CGImageAlphaInfo.PremultipliedFirst);

   //Calculate the width of the rectangle based on the progress
   float percentWidth = width * progress;

   //Create a gradient object
   CGGradient gradient = new CGGradient(CGColorSpace.CreateDeviceRGB(), components, locations);

   //Draw a linear gradient to represent the progress bar
   ctx.DrawLinearGradient(gradient, new PointF(0, 0), new PointF(percentWidth, 0), CGGradientDrawingOptions.DrawsBeforeStartLocation);

   //return a UIImage object
   return UIImage.FromImage(ctx.ToImage());
}

Note that these functions are fairly generic and you should be able to reuse them in any of your applications. See the MonoDevelop project for examples on how to use them.  They are also very simple and can be extended to draw “prettier” progress bars without too much effort.  I’ll cover drawing pie charts in my next post.

Categories: C#, iPhone, MonoTouch
Follow

Get every new post delivered to your Inbox.