WP7 Game - rotate only some controls when orientation changed - silverlight

I'm making a simple WP7 game and I have a little problem with orientation changing. My gameboard looks like this:
And I need to rotate only the numbers when orientation changed. Is there any easy way to do it? The numbers are TextBlocks and lines are rectangles. Gameboard is Canvas (but I can use Grid as well).
Or i could exclude the canvas from automatic rotating and only redraw the numbers. But I don't know how to do it either.

Using PlaneProjection should be fine:
<TextBlock.Projection>
<PlaneProjection RotationZ="90"/>
</TextBlock.Projection>
Obviously this would apply the projection immediately, so you would need to create it in code (or try using 0 for the Z value and then changing that in code (possibility of this is a long shot)) based on the data provided (and within) the OrienationChanged event handler, such as:
myTextBlock.Projection = new PlaneProjection { RotationZ = 90 };

Related

WPF 3D element rotation speed dynamic control

I have some 3D Geometry that resembles a wheel. I want to be able to rotate it but in a controllable way. I have a slider and I want to change the speed of the wheel's rotation according to the slider value without having to stop it. What is the best way to achieve that.
I know how to rotate it to a certain degree and I also know how to have some continuous Storyboard that rotates the wheel. But I don't know how to change that according to the slider's value.
After playing a lot with it, I did it. This is how:
Created a Storyboard with a "Forever" RepeatBehavior
In my code, as I receive info from USB -not from a slider anymore- I change the Storyboard's SpeedRatio accordingly (You can also bind it to a slider progress or whatever else)

Winforms semi-transparent PNG over semi-transparent PNG

I think I must be missing something obvious, but I'm unable to find this after several hours of searching. Is there no way to use a PictureBox or other control to contain an image with partial transparent/alpha-blended pixels, and place that over another image and have the blending be based on the image under it?
For example, this produces the results I want:
Place a panel on a form.
Add an OnPaint handler.
In the OnPaint handler draw 1 PNG, then draw another PNG over it, using Graphics.DrawImage for both.
This does not:
Place a PictureBox on a form and set it to a PNG.
Place another PictureBox on the form and set it to a PNG.
Place the 2nd picture box over the first.
...even if the 2nd picture box is just empty and has a background color of Transparent, it still covers the picture below it.
I've read this stems from all winform controls being windows, so by nature they aren't transparent.
...but even the 15 year old platform I'm migrating from, Borland's VCL, had several windowless controls, so it's hard to imaging winforms doesn't at least have some easy solution?
My first example above is one answer, true, but that adds a lot of work when you can only use one big panel and draw all of your "controls" inside of it. Much nicer if you can have separate controls with separate mouse events/etc. Even if not an image control, and a control I have to draw myself, that would be fine, as long as I can just put one image in each control. In VCL they called this a "paint box", just a rectangle area you could place on a form and draw whatever you want on it. Has it's own mouse events, Bounds, etc. If you don't draw anything in it, it is like it's not even there (100% transparent) other than the fact it still gets mouse events, so can be used as a "hot spot" or "target" as well.
The PictureBox control supports transparency well, just set its BackColor property to Transparent. Which will make the pixels of its Parent visible as the background.
The rub is that the designer won't let you make the 2nd picture box a child of the 1st one. All you need is a wee bit of code in the constructor to re-parent it. And give it a new Location since that is relative from the parent. Like this:
public Form1() {
InitializeComponent();
pictureBox1.Controls.Add(pictureBox2);
pictureBox2.Location = new Point(0, 0);
pictureBox2.BackColor = Color.Transparent;
}
Don't hesitate to use OnPaint() btw.
Sorry, I just found this... once I decided to Google for "winforms transparent panel" instead of the searches I was doing before, the TransPictureBox example show seems to do exactly what I need:
Transparency Problem by Overlapped PictureBox's at C#
Looks like there are 2 parts to it:
Set WS_EX_TRANSPARENT for the window style
Override the "draw background" method (or optionally could probably make the control style Opaque).

Change Alpha Blend Mode in WPF?

The System.Drawing.Graphics class has a property CompositionMode with two options: SourceOver (which, based on the alpha component, blends whatever is drawn with the background already existing) or SourceCopy which simply overwrites the background with whatever is being drawn.
Does something similar exist in WPF?
In WPF when i draw a PolyLine for example on top of another the new PolyLine always alphablends with the background. I think that is independent of the container being used. I am using a Canvas but could not find a blend mode property anywhere. What I want to do is what the SourceCopy compositionmode mentioned above does. I.e. the new PolyLine should simply overwrite whatever is already on the Canvas.
Is there a simple way to do that, short of using pixel shaders (which - as far as I understand - wouldn't work anyways because I don't have access to the Canvas backbuffer).
I am not stuck with a Canvas and would be happy to use any container that supports overwrite mode.
I currently have a solution based on a WriteableBitmap for which I obtain a System.Drawing.Graphics context and then manipulate the CompositionMode. It works but since my window is fullscreen that solution has serious performance impacts.
Clarification and example:
The WPF window is fully transparent and so is the Canvas (back ground color(0,0,0,0)). Now I draw a PolyLine with a Color.FromArgb(128,128,0,0). I now have a semi-transparent red polyline. Next I draw the same PolyLine with Color.FromArgb(0,0,0,0). The result is the same as before because of the alpha blending taking place. What I want, however, is that the red polyline is erased with the second polyline (which is exactly what the SourceCopy mode in the Graphics class does.
I think all you need to do is make sure that the brushes used to fill/stroke the PolyLine have fully opaque alpha values (i.e. 255). Then the background shouldn't be blended into it.
You could apply a Clipping Mask, this way you can provide the path to clip over the elements that are below it, but it might be tough to maintain after a lot elements are required to be clipped...

Rotating a .NET panel in Windows Forms

We use Windows Forms and custom user controls, and I would like to be able to rotate the panel hosting the userControl in a particular form. I have seen similar functionnalities with WPF, but I can't use it for the moment. Is it possible to achieve the rotation of a panel and its children using possibly built-in .NET methods or GDI+?
I have seen some pretty cool visual effect with menus that are displayed in game development, so I was wondering if it would be possible to create similar effects using Windows Forms.
Rotating a panel and its children in Windows Forms is not something directly supported, and I think it will end up being a buggy headache that could easily suck up lots of time. It's especially painful to think about when you could do this in WPF with zero lines of C# code and only a tiny bit of XAML.
You can use rotations in GDI+ by calling the RotateTransform method on a Graphics object.
However, rotating an entire control is not so simple, and will depend heavily on how the control is implemented.
If it's a composite UserControl that has other controls inside of it, you're out of luck.
If it's a sinlge control that paints itself, try inheriting the control, overriding the OnPaint method, and calling RotateTransform on the Graphics object. However, you will probably have trouble with it. In particular, you will probably need to override all of the mouse events and call the base control's events with rotated coordinates.
You can get halfway there by calling the DrawToBitmap method on your panel, then rotating the bitmap and displaying it e.g. in a PictureBox:
var bitmap = new Bitmap(panel.Width, panel.Height);
panel.DrawToBitmap(bitmap, new Rectangle(Point.Empty, panel.Size));
bitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
var pictureBox = new PictureBox();
pictureBox.Location = panel.Location;
pictureBox.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBox.Image = bitmap;
Controls.Remove(panel);
Controls.Add(pictureBox);
Rotation angles other than 90-degree increments are also possible, if you draw the bitmap into another bitmap using GDI:
var bitmap2 = new Bitmap(bmp.Width + 75, bmp.Height + 100);
var graphics = Graphics.FromImage(bmp2);
graphics.TranslateTransform(bitmap2.Width / 2, bitmap2.Height / 2);
graphics.RotateTransform(-15f);
graphics.TranslateTransform(-bitmap.Width / 2, -bitmap.Height / 2);
graphics.DrawImageUnscaled(bitmap, Point.Empty);
graphics.Dispose();
The problem of course is that you're only displaying an image of your panel, and not the panel itself, so it's no longer possible to interact with the controls inside.
That could probably be done as well, but you would have to mess with window messages, which gets quite a bit more complicated. Depending on your needs you might also be able to get away with handling click and key events on the PictureBox, manipulating the controls in the panel, and then updating the image.

WPF Custom Draw Multiple Progress Bar

In processing a group of items, I wanted to display a unified image of the status of the group, so I essentially made a Grid of a number of progressbars with transparent backgrounds and various colored foregrounds all at the same cell.
I'm running into some transparency artifacts (purple bar is actually purple under the green, and sometimes it draws over the top, etc) and it just seems a bit wasteful. So, I decided to make my own, but now I've got a bit of paralysis on how to do it. Do I use the DrawingContext in FrameworkElement's OnRender, or is there something simpler? Is there a set of general rules when it comes to making your own control?
I pondered switching to a pie chart since those are easy to come by, but its high time I did something not off-the-shelf.
Thanks!
I'm not quite sure how you intend the progressbar to combine different progresses, but if say the furthest along progress is at the bottom of the z-index and the least along progress is at the top, then I'd do something on the lines of this:
1) I would probably create a user control for this new progresbar.
2) It would have a property called NumberOfProgresses, that is tied with an array containing status of said progresses.
3) Each progress would be represented by a Border item (or perhaps something more suitable up the visual tree), because it's a simple wpf control with a background property. The background property would be set to nice a looking progress style and the progress color can be bound in the style to say the border's borderbrush property. Making it easy to set the color of the progress.
4) The user control would have a method UpdateProgress which takes the percentage value and the index of the progress in the array as parameters.
5) As progresses are updated you can either, just calculate the appropriate width (user control actual width * percentage) for the border and play around with the Z index to get it displayed at the top/bottom, or stack the borders horizontaly, set the least along progress as first, then for the rest of the progresses you'd have to substract previous progresses lengths to get the same effect.
This way there would be no transparency induced artifacts and no OnRender()...
Mind you, in WPF there should be no reason to mess with OnRender this and OnRender that, like it was required in WinForms with OnPaint.
Just set up the elements via code to get the look you want, and let WPF do it's rendering ;)
I can imagine one problem with this user control though. You'd have to provide feedback to the user as to which color belongs to which progress. But that would probably take you back to square one, meaning it's better/simpler to just display multiple progressbars.

Resources