WPF Multitouch DeltaManipulation Mouse Events Equivalent? - wpf

i have a small demo app with a grid. this grid contains a image. i use the following code to scale and translate the image with touch.
private void manipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
Matrix matrix = imagematrix.Matrix;
matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);
matrix.ScaleAt(e.DeltaManipulation.Scale.X, e.DeltaManipulation.Scale.Y,
e.ManipulationOrigin.X, e.ManipulationOrigin.Y);
imagematrix.Matrix = matrix;
e.Handled = true;
}
The matrix is placed at rendertransformation property on the image.
I would like to have the same functionality in a other demo app without touch but with mouse event handlers.
I tried something like this for the translation on mouse move but its not the same :(
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Vector delta = lastPoint - e.GetPosition(canvascontrol);
Matrix matrix = PART_MATRIX.Matrix;
if(delta.X > 0)
matrix.OffsetX += 1;
else
matrix.OffsetX -= 1;
if (delta.Y > 0)
matrix.OffsetY += 1;
else
matrix.OffsetY -= 1;
imagematrix.Matrix = matrix;
}
base.OnMouseMove(e);
}
lastPoint is the first point onmouseleftbuttondown.
Thanks.

I am not sure, if this is the answer you are looking for but, the Thumb control gives you a DragDelta, if you wrap a Thumb into a template and then assign the template to the image object, or assign the image as a template to the Thumb.

Related

How can I draw a line to an array?

I'd like to store a mouse trail (or other visual data), without it being drawn to the screen.
How can I do the following, but save the display data to an Arrary so it's not drawn to the stage?
line(mouseX, mouseY, pmouseX, pmouseY);
I have a suspicion I need to toggle between different display data each draw() by:
clearing the screen
loading target display data
drawing to the screen
store back out to target data
I'm not sure how to go about it yet or if there's a better approach.
#Majlik example is really cool (voted up). Just to add that you don't need a PGraphic if you only want to store the data. And you can use PVector to store the data in mouseMoved().
here is my attempt ;)
ArrayList <PVector> points = new ArrayList <PVector>();
boolean print = false;
void setup(){
size(400,400);
background(255);
}
void draw(){
if(print && points.size()>1){
for(int i = 0; i < points.size()-1; i++){
float stX = points.get(i).x;
float stY = points.get(i).y;
float ndX = points.get(i+1).x;
float ndY = points.get(i+1).y;
line(stX, stY, ndX, ndY);
}
print = false;
}
}
void mouseMoved(){
points.add(new PVector (mouseX, mouseY));
}
void keyPressed(){
if(key == ' ' ){
background(255);
print = true;
}
}
Using PGraphics to draw lines to different display (you can switch it on/off by pressing any key) and Arraylist to store position of mouse you can achieve something like this:
PGraphics pg;
ArrayList<Integer> points = new ArrayList();
boolean visible = true;
void setup() {
size(400, 400);
pg = createGraphics(width, height);
}
void draw() {
background(100);
if(points.size() >= 100){
points.remove(0);
points.remove(1);
}
points.add(mouseX);
points.add(mouseY);
pg.beginDraw();
pg.background(100);
for(int i = 2; i < points.size()-4; i += 2){
pg.stroke(255/100*(i+1));
pg.line(points.get(i), points.get(i+1), points.get(i+2), points.get(i+3));
}
pg.endDraw();
if(visible)
image(pg, 0, 0);
}
void keyPressed() {
visible = !visible;
}

How do I carry forward variable values in WinForms?

I'm trying to make it so that there is a total at the bottom depending on what buttons are pressed (when I hit the 'calculate' button). If button 1 is pressed, it shows 30 points, if button 2, it shows 60 points, if button 3 is pressed, it shows 90 points. But any or all of them can be pressed, so if 1 and 3 are pressed, it shows 120.
I know that there is some way to carry forward the value of a variable, but I can't think of it or find it (I'm very new at this). I'm also not sure if 'if' statements are the best way to handle this (especially if I end up having 25 or so buttons), so if there is a better way, please let me know.
(I have it so that the button turns lime green if pressed.)
int score1 = 0;
if (button1.BackColor == Color.Lime)
{
label10.Text = (30 + score1).ToString();
}
else label10.Text = score1.ToString();
if (button2.BackColor == Color.Lime)
{
label10.Text = (60 + score1).ToString();
}
else label10.Text = score1.ToString();
if (button3.BackColor == Color.Lime)
{
label10.Text = (90 + score1).ToString();
}
else label10.Text = score1.ToString();
Thank you.
I think you just need to add a form variable in your class to hold the running total:
private int totalScore = 0;
You can have a method to set the background color and add to the score:
private void SetBackgroundAndAddToTotal(Button button, int score)
{
if (button.BackColor != Color.Lime)
{
button.BackColor = Color.Lime;
this.totalScore = this.totalScore + score;
}
}
Inside the Click handler for each button that needs to affect the total, you can call SetBackgroundAndAddToTotal().
private void button1_Click(object sender, EventArgs e)
{
SetBackgroundAndAddToTotal(button1, 30);
}
private void button2_Click(object sender, EventArgs e)
{
SetBackgroundAndAddToTotal(button2, 60);
}
// etc.
Then, in your click handler for your "Calculate" button, you can just grab the already-calculated total from the form variable and display it:
private void btnCalculate_Click(object sender, EventArgs e)
{
label10.Text = this.totalScore.ToString();
}
Would that work?

WPF Ellipse size

I have found this question here: How to populate a WPF grid based on a 2-dimensional array and I wanted to use that the marked solution. And it also seems to work quite nice but there is one problem and that problem is that I am using ellipses to display my data. So every item equals one ellipse.
And here is the problem: The ellipses are requesting on Measure only a size of x = 0, y = 0.
So my problem is that there is displayed nothing. So I tried to create a custom Stackpanel:
public class StretchStackPanel : StackPanel
{
protected override Size MeasureOverride(Size constraint)
{
Size result = constraint;
result.Width = result.Width == Double.PositiveInfinity ? Double.MaxValue : result.Width;
result.Height = result.Height == Double.PositiveInfinity ? Double.MaxValue : result.Height;
if (this.Orientation == System.Windows.Controls.Orientation.Horizontal)
result.Height = result.Width / InternalChildren.Count;
return result;
}
protected override Size ArrangeOverride(Size arrangeSize)
{
var size = base.ArrangeOverride(arrangeSize);
double elementLength;
if (Orientation == System.Windows.Controls.Orientation.Horizontal)
elementLength = size.Width / InternalChildren.Count;
else
elementLength = size.Height / InternalChildren.Count;
double current = 0;
foreach (UIElement e in InternalChildren)
{
Rect result;
if (Orientation == System.Windows.Controls.Orientation.Horizontal)
{
result = new Rect(current, 0, elementLength, size.Height);
current += result.Width;
}
else
{
result = new Rect(0, current, size.Width, elementLength);
current += result.Height;
}
e.Arrange(result);
}
return size;
}
}
But there is a very strange behaviour. There are very very smalle margins between the items and the seem to be random. If I resize you can see them moving.
here are two screenshots:
I also tried to use a Uniformgrid with columns only instead of Stackpanel and set an itemstyle with a fixed height using a ViewBox around the Itemscontrol.

Clipping image using Path in Silverlight

How to clip image in Silverlight using custom Path (in code behind, not in XAML).
I have puzzle piece like shape written in path and want to use it to clip any image.
Currently it works by clipping using rectangle, The code is (C#):
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
int NUM_COLUMN = 8;
int NUM_ROW = 8;
double gridWidth = 60;
double gridHeight = 60;
string url = "Images/Sun.png";
// C#
for (int i = 0; i < NUM_COLUMN; i++)
{
for (int j = 0; j < NUM_ROW; j++)
{
double offsetX = (double)i * gridWidth;
double offsetY = (double)j * gridHeight;
Image image = new Image();
image.Source = new BitmapImage(new Uri(url, UriKind.Relative));
// clip the image
RectangleGeometry r = new RectangleGeometry();
r.Rect = new Rect(offsetX, offsetY, gridWidth, gridHeight);
image.Clip = r;
this.ClipCanvas.Children.Add(image);
}
}
}
There is only one Canvas in XAML called ClipCanvas.
Okay, not ideal. But works from the code-behind
Image image = XamlReader.Load(#"<Image xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" Clip=""M 41.1,33.7 C 41.1,33.7 39.9,32.2 39.9,30.8 C 39.9,30.6 39.5,29.8 39.3,29.5 C 39.1,29.3 38.4,28.6 37.8,28.2 C 37.2,27.9 35,26.6 34.6,22.4 Z "" />") as Image;
image.Source = new BitmapImage(new Uri("Desert.jpg", UriKind.Relative));
Set up in the clip in Xaml, and create the Image using an XamlReader. Tried other approaches, and this was the only one that worked.

Subclassed ListView column 0 displays corrupted text on Windows 7

Windows 7 (64 bit), .NET 4 (32 bit app)
I have a subclassed System.Windows.Forms.ListView comprising 2 columns displayed
in "Details" view. Only text fields are involved. The list comprises about 100
rows. On initial display all fields are drawn clearly but when scrolling or
"paging" with the scroll bar the text of some fields in the first column becomes
unreadable. It appears to be overwriten with random lines and blotches.
Is there anything that I can do to ensure that the text is clearly drawn in column 0?
The effect is diminished (clarity improved) when using remote desktop across a
LAN.
The effect disappears (all text is drawn clearly) when using remote desktop
across a WAN.
The ListView has always drawn perfectly on Windows XP.
For the purposes of a stripped down test, column header and DrawItem calls are ingored. The problem area is OnDrawSubItem which comprises the code
protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
{
using (StringFormat sf = new StringFormat(StringFormatFlags.NoWrap))
{
Rectangle rect = new Rectangle(e.Bounds.Left
,e.Bounds.Top, e.Bounds.Width, e.Bounds.Height);
e.Graphics.DrawString(e.SubItem.Text, this.Font, Brushes.Black
,rect, sf);
}
base.OnDrawSubItem(e);
}
The following is the complete code that reproduces the problem:
using System;
using System.Windows.Forms;
using System.Drawing;
///
/// Build by saving to a file called LVTrial.cs and then executing "csc LVTrial.cs"
/// Scroll list up and down on a windows 7 box and the first column of text is corrupted.
///
class MyListView : ListView
{
Random randomiser = new Random();
private const int NUM_ROWS = 100;
private const int NUM_COLS = 2;
public MyListView()
{
this.Location = new System.Drawing.Point(23, 25);
this.OwnerDraw = true;
this.Size = new System.Drawing.Size(625, 387);
this.TabIndex = 0;
this.UseCompatibleStateImageBehavior = false;
this.View = System.Windows.Forms.View.Details;
for (int ii = 0; ii < NUM_COLS; ii++)
{
this.Columns.Add((
(System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())));
}
for (int ii = 0; ii < NUM_ROWS; ii++)
{
this.Items.Add( new ListViewItem(
new string[NUM_COLS] { CreateRandomString(1, 6), CreateRandomString(1, 6) } ) );
}
}
protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
{
using (StringFormat sf = new StringFormat(StringFormatFlags.NoWrap))
{
Rectangle rect = new Rectangle(e.Bounds.Left
,e.Bounds.Top, e.Bounds.Width, e.Bounds.Height);
e.Graphics.DrawString(e.SubItem.Text, this.Font, Brushes.Black
,rect, sf);
}
base.OnDrawSubItem(e);
}
private string CreateRandomString(int minLength, int maxLength)
{
string str = string.Empty;
int length = randomiser.Next(minLength, maxLength + 1);
for (int ii = 0; ii < length; ii++)
{
int asciiChar = randomiser.Next(32, 126); // ascii range
str += Convert.ToChar(asciiChar);
}
return str;
}
}
class LVTrial : Form
{
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new LVTrial());
}
private LVTrial()
{
MyListView myListView = new MyListView();
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(674, 440);
this.Controls.Add(myListView);
this.Text = "LVTrial";
}
}
I have recorded this as a Windows 7 bug at https://connect.microsoft.com/VisualStudio/feedback/details/657909/subclassed-listview-column-0-displays-corrupted-text-on-windows-7
My own workaround for the problem was to insert an additional column at position 0. I now draw a rectangle with a transparent brush in column 0 for each item. All of which stops the text in the column to the right being drawn corrupt. I imagine drawing an image would achieve the same thing but I have not tried it. You can't hide this dummy column as the problem simply transfers to the second column (i.e. the first visible coolumn).
Another tip is that it seems to be performance related. The bug was more likely to occur with 100 items in the list view than 10,000.

Resources