Creating an advanced HUD - wpf

I'm making an interface for the AR Drone Quadcopter in WPF.
I neen some stuff on my HUD to make it usable.
One of the more advanced controls on the HUD is the artificial horizon, which tells the pilot the craft's current alignment to the horizon.
I have these 3 PNGs
The first image I will move (The current pitch of the craft) and rotate (The current roll of the craft).
I will put the second image over the first, this one will only rotate around the center axis, it has ticks at certain degrees which will visualize the craft's roll even more.
The last one I will put on top of the second, this image just a visual improver.
Then I want to mask first image so that you only see whats inside the circle in image 2.
Last but not least I want to add a textblock to it and display the current altitude
The result will look something like this
I know how to rotate and move the image, but how do I place the images on top of each other, and how do I mask the first image?
edit: Thanks to Ben I've gotten this far:
But I also need to translate the image Y position (The pitch of the aircraft)
When I add the translate transform I also translate the Clip (Mask) how can I translate the image without moving the mask?

A little sample that how you can use DrawingGroups and a ClipGeometry inside it.
<Grid>
<Image Source="Images\Background.jpg" />
<Image>
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<DrawingGroup>
<!-- You can rotate a DrawingGroup -->
<DrawingGroup.Transform>
<RotateTransform Angle="-15" CenterX="50" CenterY="50" />
</DrawingGroup.Transform>
<ImageDrawing ImageSource="Images\last.png" Rect="0,0,100,100" />
<DrawingGroup.ClipGeometry>
<EllipseGeometry Center="50,50" RadiusX="25" RadiusY="25" />
</DrawingGroup.ClipGeometry>
</DrawingGroup>
<DrawingGroup>
<ImageDrawing ImageSource="Images\middle.png" Rect="0,0,100,100" />
<ImageDrawing ImageSource="Images\outer.png" Rect="0,0,100,100" />
</DrawingGroup>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Grid>

I was tired last night :D
To get the background to rotate and translate but not the Clipping was just to put the background in a sub group to the clipping group... Now it works!
<Image Width="240" Height="240">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<DrawingGroup>
<DrawingGroup>
<DrawingGroup.Transform>
<TransformGroup>
<RotateTransform Angle="-15" CenterX="120" CenterY="120" />
<TranslateTransform Y="-20" />
</TransformGroup>
</DrawingGroup.Transform>
<ImageDrawing ImageSource="Images\pNxVK.png" Rect="0,0,240,240" />
</DrawingGroup>
<DrawingGroup.ClipGeometry>
<EllipseGeometry Center="120,120" RadiusX="60" RadiusY="60">
</EllipseGeometry>
</DrawingGroup.ClipGeometry>
</DrawingGroup>
<DrawingGroup>
<ImageDrawing ImageSource="Images\zUr8D.png" Rect="0,0,240,240" />
<ImageDrawing ImageSource="Images\XPZW9.png" Rect="0,0,240,240" />
</DrawingGroup>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>

Related

Wpf canvas grid with coordinates

I have following canvas Code:
<Canvas>
<Canvas.Background>
<DrawingBrush TileMode="Tile" Viewport="0,0,40,40"
ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,400,400"/>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Red" Thickness="1"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Canvas.Background>
</Canvas>
This canvas generates a grid like you can find it on excel.Now I want to know if ist possible to generate the coordinates too. With cooridnates I mean that the first top row in the first fiels has a tiny text in it that says "A0" and the next one has "B0" and so every cell has coordinates like Excel.Would this be possible?

XAML graphic vector as image source

Now many graphics designers provide the images as xaml file not ico, png, ..., How can I use a xaml file as image source?
Thanks
From the MSDN
<Image>
<Image.Source>
<DrawingImage PresentationOptions:Freeze="True">
<DrawingImage.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
<EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
</GeometryGroup>
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="Blue" />
<GradientStop Offset="1.0" Color="#CCCCFF" />
</LinearGradientBrush>
</GeometryDrawing.Brush>
<GeometryDrawing.Pen>
<Pen Thickness="10" Brush="Black" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
Instead of in-lining the GeometryDrawing you could refer to it as a static resource that you keep in a Resourcedictionary.
<Image>
<Image.Source>
<DrawingImage PresentationOptions:Freeze="True"
Drawing="{StaticResource myDrawing}">
</Image.Source>
</Image>
You will also find that you can show the drawing only once this way. So if you want this image to be present in the UI in multiple places, put the Image in a control template and style the controls with the template.
Thanks too all, this approach I know, my question was what happens when I have 100 xaml graphics files provided by a designer, now I have to extract the content from each file to move in a resource dictionary and set a key for each. I ask only if a more easy way as time.
Thank again too all.
I got a graphic like this
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Width="128" Height="128">
<Canvas Width="10240" Height="10240">
<Path Data="M5986 6814l828 -828c124,-124 328,-124 452,0l2428 2428c124,124 124,328 0,452l-828 828c-124,124 -328,124 -452,0l-2428 -2428c-124,-124 -124,-328 0,-452z" Fill="#EDC87E"/>
<Path Data="M6082 5442l412 412 -640 640 -412 -412c-534,401 -1197,638 -1916,638 -1764,0 -3194,-1430 -3194,-3194 0,-1764 1430,-3194 3194,-3194 1764,0 3194,1430 3194,3194 0,719 -237,1382 -638,1916zm-2556 -4471c-1411,0 -2555,1144 -2555,2555 0,1411 1144,2555 2555,2555 1411,0 2555,-1144 2555,-2555 0,-1411 -1144,-2555 -2555,-2555z" Fill="#808080"/>
</Canvas>
</Viewbox>
This can be user very easy as a content to a Content control, but to youse this for a control which requires Image source I cannot I have to transform to:
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Geometry="M5986 6814l828 -828c124,-124 328,-124 452,0l2428 2428c124,124 124,328 0,452l-828 828c-124,124 -328,124 -452,0l-2428 -2428c-124,-124 -124,-328 0,-452z" Brush="#EDC87E">
<GeometryDrawing.Pen>
<Pen Thickness="1000" Brush="Blue"></Pen>
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="M6082 5442l412 412 -640 640 -412 -412c-534,401 -1197,638 -1916,638 -1764,0 -3194,-1430 -3194,-3194 0,-1764 1430,-3194 3194,-3194 1764,0 3194,1430 3194,3194 0,719 -237,1382 -638,1916zm-2556 -4471c-1411,0 -2555,1144 -2555,2555 0,1411 1144,2555 2555,2555 1411,0 2555,-1144 2555,-2555 0,-1411 -1144,-2555 -2555,-2555z" Brush="#808080"/>
</DrawingGroup.Children>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
The work in to trivial :(

Graph paper with elongated grid sections?

I am trying to make some Graph Paper using WPF using the DrawingBrush.
I found the following example on MSDN which is pretty close to what I want but not exactly. I want to do this is pure XAML. I am fairly new to WPF.
<DrawingBrush x:Key="GridTile"
Viewport="0,0,10,10"
ViewportUnits="Absolute"
TileMode="Tile">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Geometry="M0,0 L1,0 1,0.1, 0,0.1Z" Brush="Blue" />
<GeometryDrawing Geometry="M0,0 L0,1 0.1,1, 0.1,0Z" Brush="Red" />
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
Currently this generates
I want to generate
with a width of 3cm and each row being 4mm
I will use this tile my background or rather the DrawingBrush TileMode takes care of that for me.
Change the size of the Brush so the Viewport has more height than width, and change the Geometry accordingly so the lines still appear 1px thick.
<Window x:Class="WPFTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF" SizeToContent="WidthAndHeight">
<Window.Resources>
<DrawingBrush x:Key="GridTile" Viewport="0,0,4,16"
ViewportUnits="Absolute" TileMode="Tile">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Geometry="M0,0 L1,0 1,0.05 0,0.05Z" Brush="Black"/>
<GeometryDrawing Geometry="M0,0 L0,1 0.1,1 0.1,0Z" Brush="Black"/>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Window.Resources>
<Rectangle Height="512" Width="512" Stroke="Black" StrokeThickness="0"
Fill="{StaticResource GridTile}"/>
</Window>

How to create a Brush with a background in WPF?

I want to create a brush that draws a ellipse on the top-right corner, I tried this:
<DrawingBrush Stretch="None" AlignmentX="Right" AlignmentY="Top">
<DrawingBrush.Drawing>
<GeometryDrawing Brush="Green">
<GeometryDrawing.Geometry>
<EllipseGeometry RadiusX="60.0" RadiusY="60.0" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
The ellipse is in its position, but the rest area is transparent. Can I create a brush that draws an ellipse on the top-right corner with a non-transparent background? Can I use another brush as background?
Your DrawingBrush can contain a DrawingGroup with multiple drawings, each with its own brush. Here I have added a pale green RectangleGeometry that fits behind your ellipse and serves as the background:
<DrawingBrush Stretch="None" AlignmentX="Right" AlignmentY="Top">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="PaleGreen">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="-60,-60,120,120" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="Green">
<GeometryDrawing.Geometry>
<EllipseGeometry RadiusX="60.0" RadiusY="60.0" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
Given the requirement to have the background fill all available space, I recommend giving the Window.Background the fill brush and then overlaying another element in the upper right corner to contain the ellipse.

Background with several paths

Is there a way I can put a background like this in a border:
The problem in there is that both the circle and the square must be a path (in my real problem I actually have 3 paths and they're gradients), and this makes it extremely problematic to resize, align, etc. I saw this solution but I had already tried using a viewbox and it didn't solve my problem.
Is there a way I can combine both the square and the circle into a path and keep the colors, and then set it as a background?
I don't have the real button around here, so I'll post it tomorrow, but it has several gradients to make some glossy effect and some Bezier curves to make the effect more "realistic". In the mean time the effect looks something like this:
Thanks for any help.
Don't quite understand why the ViewBox would not work but alternatively you can use a DrawingBrush, e.g.:
<Border Width="300" Height="300">
<Border.Background>
<DrawingBrush>
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="Blue">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,100,100" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="Red">
<GeometryDrawing.Geometry>
<EllipseGeometry Center="50,50" RadiusX="35" RadiusY="35" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Border.Background>
</Border>

Resources