March 2009 Entries

Dynamically loading XAML

For the bartender, I’m going pure WPF.  Since Expression Blend 3.0 now can import Adobe Illustrator files, my friend Ian can use the tools he knows best and produce me some amazing graphics.  I don’t do amazing graphics so I’m going to show how to do it with simple shapes.

Based off the code in my prior post for my Big Button, I’ll be dynamically adding stuff in.  Before and After Screen shots:

imageimage

Base XAML as it was slightly modified.  I’ve added in another grid to load the items into.

<Button Name="bigButton" Margin="14,6,14,71.517" Click="bigButton_Click">
	<Grid>
		<Grid.RowDefinitions>
			<RowDefinition Height="*"/>
			<RowDefinition Height="30"/>
		</Grid.RowDefinitions>
		<Grid Grid.Row="0" Name="DyanmicXamlLoad">
			<Image Name="image1" Stretch="UniformToFill" 
			Source="Koala.jpg" StretchDirection="Both" Margin="10" 
			VerticalAlignment="Center" HorizontalAlignment="Center"/>
		</Grid>
		<Label Grid.Row="1" HorizontalAlignment="Center" FontSize="20" Padding="0">
			change background
		</Label>
	</Grid>
</Button>

Now the c# for the loading XAML:

var stringReader = new StringReader(
	@"<Grid xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" 
	xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
		<Ellipse Height=""100"" Width=""100"" StrokeThickness=""5"" 
			Stroke=""Black"" Name=""testObject"" Fill=""Gold""/>
	</Grid>"
);
var xmlReader = new XmlTextReader(stringReader);
var element = (UIElement)XamlReader.Load(xmlReader);

DyanmicXamlLoad.Children.Clear();
DyanmicXamlLoad.Children.Add(element);

So key things when adding in dynamic code, you need to remember to add in the name space else the XamlReader.Load will fail.  Another thing is when you load this dynamically loaded element, it loads in under a different name scope.  Due to this, the FindName won’t return the dynamically loaded elements if you read the documentation.   MSDN has an article on this and gives some work arounds for this.

My work around is the following.

Brush brush = new SolidColorBrush(getRandomColor());
if (DyanmicXamlLoad.Children.Count > 0)
{
	var element = ((FrameworkElement)DyanmicXamlLoad.Children[0]).FindName("testObject");

	if (element != null && element is Shape)
		((Shape)element).Fill = brush;
}

So my work around is knowing the element I’m loading into, verifying it has children.  If it does, grab the first one and then do the FindName on it.

But now I can dynamically load my drink glasses and change the color of the liquid! 

YAP (yet another project) – Webcam software … image processing edition

image

So I saw that Jeff Sandquist’s webcam solution had some issues and I was kind of surprised there wasn’t a decent solution out there.  I won’t pledge a great application, but I will pledge a decent one that can be altered to fit your needs.

So I have three requirements for this:

  • Uploads to FTP
  • Uploads to flickr also
  • Can embed a time stamp with a nice transparency

From a high level, here is the application’s load function.  Note this is just the image processing part.  Since this is GDI+, we want to be very careful to dispose of our graphic objects since we don’t want memory leaks.  Now I have not verified this is memory leak free so be warned.

We do the resize so we don’t resize the text we’ll pop on top of the image.  I did some research and found some nice guy did a bit of help for me when it came to resizing over at Switch On The Code.  I won’t really repeat that code as they’ve already done it.  I tweaked it slightly but for the most part, their code works.

var returnValue = new Bitmap("C:\\test.jpg");
returnValue = (Bitmap)resizeImage(returnValue, new Size(250, 400));

int rectHeight = 25;
addRectangle(returnValue, 0, returnValue.Height - rectHeight, 
	returnValue.Width, rectHeight, Color.FromArgb(180, Color.Black));
addImageText(returnValue, "Hi from Mix'09", 0, 
	returnValue.Height - rectHeight, Color.White);
pictureBox1.Image = returnValue;

After that, we’ll pop on the rectangle overlay then put on the text. 

private static void addImageText(Image imgToAddText, 
	string text, int x, int y, Color color)
{
	using (Graphics g = Graphics.FromImage(imgToAddText))
	{
		g.SmoothingMode = SmoothingMode.AntiAlias;
		g.DrawString(text, 
			new Font("Arial", 20, GraphicsUnit.Pixel), 
			new SolidBrush(color), 
			x, y);
		g.DrawImage(imgToAddText, 
			0, 0, imgToAddText.Width, imgToAddText.Height);
	}
}

private static void addRectangle(Image imgToAddRect, 
	int x, int y, int width, int height, Color color )
{
	using (Graphics g = Graphics.FromImage(imgToAddRect))
		g.FillRectangle(
			new SolidBrush(color), 
			new Rectangle(x, y, width, height));
}

So after all that, here is the image after all the processing.  Next up, DirectShow.Net integration followed by some FTP and Flickr action.

XAML, getting your feet wet

Coming from an ASP.Net and WinForm background, XAML seems like it would be fairly easy to get a handle on but I’m having to take a bit more cautious approach to it.

Win32 Button From DrunktenderXAML is XML as is HTML and kind of has some CSS like attributes but at the same time they are different.  For this reason, I’m taking baby steps to port my old bartending application over.  The first thing I’m going to attack is the button.  Here is the button from the Win32 application.  Yes, I know it looks WPF like but that is just chrome my friend and myself helped paint onto a default Win32 button.

Since I’m a developer, I’ll be using Visual Studio 2008 but Expression Blend will do this far better.

To recreate this in WPF, I have to do a few things to do and a new requirement.  I need an image / XAML glass, text at the bottom, and the new requirement is to have it scale.  With a XAML glass image, I can change the liquid color dynamically along with resize it with no fidelity lose since the image is vector.

WPF Button The current button (on the right), I have isn’t fully worked out as it can’t import XAML into it but that is just a small issue.  I’ve done this in Silverlight so I know I can do it.

This seems pretty straight forward on how to get everything to work correctly, but let me show you how I did this.  Right now this is pure XAML, no C# or VB.Net exists yet.

For the XAML, I used a Grid, Label, Image and some RowDefinitions to get this worked out.  I can do this since in XAML, I can nest objects within one another’s container.  This lets me put an image / placeholder for XAML and a label within the button so I can extend out the button extremely easily.

<Button Name="bigButton" Height="250" Width="250">
	<Grid>
		<Grid.RowDefinitions>
			<RowDefinition Height="*"/>
			<RowDefinition Height="30"/>
		</Grid.RowDefinitions>
		<Image Grid.Row="0" Name="image1" 
			Stretch="UniformToFill" Source="Koala.jpg" 
			StretchDirection="Both" VerticalAlignment="Center" 
			HorizontalAlignment="Center" Margin="10" />
		<Label Grid.Row="1" HorizontalAlignment="Center" 
			FontSize="20" Padding="0">test</Label>
	</Grid>
</Button>

WPF Wire FrameWhat this produces (I removed the koala image) is a grid system that looks like this.  Breaking down the XAML, we see I have 2 rows I defined in the grid.  I have one that is floating and the other is a fixed height of 30.  Then I can say Grid.Row="X" to the element I want to attach to this Row.  In this instance I made the Label to stay at 30 and the Image to take up the rest of the space.  When the button grows or shrinks, the image will be effected, not the text.

Other things I had to do was tweak a bunch of settings on the Image.  I set Stretch to UniformToFill and ScretchDirection to Both along with centering both the vertical and horizontal alignment so when the image grows, it stays centered and in proper proportion.

Up next is dynamically loading and setting a property (or properties) from that XAML!  And with Expression Blend 3.0, my designer can hand me Illustrator files and I can directly import them in!

Drunktender – live alcohol test by making Irish Car Bombs

I was asked to make a quick demo for Ping(http://channel9.msdn.com/tags/ping/) on MSDN’s Channel 9 (http://channel9.msdn.com).  I used this as an excuse to drink some car bombs along with test the system in a live setting with actual liquid and proper pouring.  Here is the system in action.

So how did I create this simple app?  I have my relay source code pretty much locked down so all I need to do is fire off one command:

relay.AddCommand(
	new RelayCommand(1, 1, 1000),
	new RelayCommand(1, 0, 1000),
	new RelayCommand(1, 2, 7000)
	);

In the future, I’ll create a new class called Bartender so I can do this (and a few other ways):

Bartender.PourDrinkByName("Irish Car Bomb");

Since we know all good object oriented programmers know that objects should only talk to their immediate friends, (Law of Demeter - http://en.wikipedia.org/wiki/Principle_of_least_knowledge), my Drink object call should know how to make the drinks but shouldn’t know how to pour them as there is no need for that class to know about the relays.  It has to insert, remove, update, return data for Drinks.

How can I do the PourDrinkByName method call and still obey the law of Demeter?  The system will look up how to make the drink.  Then I can look up what alcohol is on which valve is on what bank and relay.  Since I know what drinks the system currently is armed with, I can also do neat stuff like only return drinks the system can make!

Just for those new to the project, this is a resurrected I did for Maker Faire a few years back.  I have the source code and SQL for that version over on Peace Love Code.

A new UI

imageThere really is nothing really wrong with the current one however there are a lot of aspects I dislike.  I find some of the colors too washed out and the fact I used Win32 instead of WPF makes scalable an issue.  I’m chatting with the same guy who designed the first version, Ian Hill, to help redo the UI with me.  WPF will allow me to have non-rasterized graphics via XAML that can scale and won’t be pre-rendered.  It will also let me have animations and some neat flow control abilities out of the box.

I whipped up some mocks on the way to a work event.  Few more are on flickr.

New UI mocks for WPF by you.New UI mocks for WPF by you.New UI mocks for WPF by you.

Remember, a great user interface makes all the difference.  Ian rules so I’m asking him again for some help as I am a lonely dev-signer, not a full blown designer.

Relay test with valves hooked up

Some relay board building progress

I’m big on being able to disassemble / replace bits with little effort.  This was a hard learned lesson from other projects.

IMG_5494IMG_5495IMG_5492IMG_5500