Windows phone columns and grids during orientation change - windows-phone-8

Hey people I have this in my xml
<Grid x:Name="LayoutRoot" Background="Black">
<Grid Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="72"/>
<RowDefinition Height="*"/>
<RowDefinition Height="90"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="72"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="90"/>
</Grid.ColumnDefinitions>
<StackPanel x:Name="FirstBorder" Background="Red" Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="0" Grid.RowSpan="3"/>
<Grid Grid.Column="1" Grid.Row="0" Grid.RowSpan="3" x:Name="LivePreviewTapTarget">
<Canvas>
<Rectangle x:Name="CameraRectangle" Width="638" Height="480" Fill="{Binding PreviewBrush}">
<Rectangle.RenderTransform>
<CompositeTransform x:Name="LivePreviewTransform"/>
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
</Grid>
<Border x:Name="SecondBorder" Background="Yellow" Grid.Column="2" Grid.Row="0" Grid.RowSpan="3"></Border>
And even this red panel is in first column only, when I run the app, it expands somehow (you can see that on the image attached, there is red border over camera view). What am I doing wrong?
NEW PROBLEM!
When I change page rotation I get this in portrait view. The xaml of the page is the same. And I do this in OnOrientationChanged event handler.
if (IsPortrait(Orientation))
{
Grid.SetRow(FirstBorder, 0);
Grid.SetColumn(FirstBorder, 0);
Grid.SetColumnSpan(FirstBorder, 3);
Grid.SetRow(LivePreviewTapTarget, 1);
Grid.SetColumn(LivePreviewTapTarget, 0);
Grid.SetColumnSpan(LivePreviewTapTarget, 3);
Grid.SetRow(SecondBorder, 2);
Grid.SetColumn(SecondBorder, 0);
Grid.SetColumnSpan(SecondBorder, 3);
CameraRectangle.Width = 480;
CameraRectangle.Height = 638;
}
else
{
Grid.SetColumn(FirstBorder, 0);
Grid.SetRow(FirstBorder, 0);
Grid.SetRowSpan(FirstBorder, 3);
Grid.SetColumn(SecondBorder, 2);
Grid.SetRow(SecondBorder, 0);
Grid.SetRowSpan(SecondBorder, 3);
Grid.SetColumn(LivePreviewTapTarget, 1);
Grid.SetRow(LivePreviewTapTarget, 0);
Grid.SetRowSpan(LivePreviewTapTarget, 3);
CameraRectangle.Width = 638;
CameraRectangle.Height = 480;
}
if (IsPortrait(Orientation))
{
_livePreviewTransform.Rotation = _viewModel.ViewfinderRotation;
_livePreviewTransform.CenterX = 240;
_livePreviewTransform.CenterY = 400;
_livePreviewTransform.TranslateX = -100;
_livePreviewTransform.TranslateY = -160;
}
else if (Orientation == PageOrientation.LandscapeRight)
{
_livePreviewTransform.Rotation = 180;
_livePreviewTransform.CenterX = 400;
_livePreviewTransform.CenterY = 240;
_livePreviewTransform.TranslateX = -160;
_livePreviewTransform.TranslateY = 0;
}
else
{
_livePreviewTransform.Rotation = 0;
_livePreviewTransform.CenterX = 400;
_livePreviewTransform.CenterY = 240;
_livePreviewTransform.TranslateX = 0;
_livePreviewTransform.TranslateY = 0;
}
var scaleX = 1.0;
if (_viewModel.CameraSensorLocation == CameraSensorLocation.Front)
scaleX = -1.0;
_livePreviewTransform.ScaleX = scaleX;
Here is the page look in portrait mode.

Strange, I've tested your code on my HTC 8X and it works just fine. Maybe the red color is already part of the PhotoCamera stream on your device?
As a workaround I'd recommend adding few pixels of negative margin to the the CameraRectangle element, that should hide the red borders.

Related

Creation of heat map(spectrogram) using Winrt xaml toolkit multiple line series

I am creating heat maps in Windows store apps 8.1 using algorithm provided in stack overflow.
first approach:
public Color HeatMapColor(decimal value, decimal min, decimal max)
{
decimal val = (value - min) / (max - min);
int r = Convert.ToByte(255 * val);
int g = Convert.ToByte(255 * (1 - val));
int b = 0;
return Color.FromArgb(255,r,g,b);
}
second approach:
public Brush getColourTemp(int maxVal,int minVal ,double actual )
{
int maxVal = 70000000;
int minVal = 100000;
var midVal = (maxVal - minVal) / 2;
int intR;
int intG;
int intB = Convert.ToInt32(Math.Round(0.0));
if (actual >= midVal)
{
intR = 255;
intG = Convert.ToInt32(Math.Round(255 * ((maxVal - actual) / (maxVal - midVal))));
}
else
{
intG = 255;
intR = Convert.ToInt32(Math.Round(255 * ((actual) - minVal) / (midVal - minVal)));
}
// Color background = Color.FromArgb(255, (byte)ran.Next(255), (byte)ran.Next(255), (byte)ran.Next(255));
Color background = Color.FromArgb(255, (byte)intR, (byte)intG, (byte)intB);
return new SolidColorBrush(background);
//byte[] bytes = BitConverter.GetBytes(actual);
//return new SolidColorBrush(Color.FromArgb(bytes[0], bytes[1], bytes[2], bytes[3]));
// return to_rgb(intR, intG, intB);
}
But in both the case blue colour is zero why. I need blue color in heat map also can any one help me out.
I am creating heat map using Winrt xaml toolkit line graphs
code details
for (int i = 0; i <= 200; i++)
{`enter code here`
if (i > 25)
{
LineChart.Series.RemoveAt(0);
}
List<FinancialStuff> financialStuffList = new List<FinancialStuff>();
LineSeries line = new LineSeries();
line.Title = "";
line.IndependentValuePath = "Name";
line.DependentValuePath = "Amount";
for (int j = 0; j < 256; j++)
{
financialStuffList.Add(new FinancialStuff() { Name = i, Amount = j - 130, FavoriteColor = ConvertTotalToRgb(i, j) });
}
line.ItemsSource = financialStuffList;
line.DataPointStyle = style;
LineChart.Series.Add(line);
if (i >= 25)
{
await Task.Delay(TimeSpan.FromSeconds(1));
}
//******************************************************************************
public Brush ConvertTotalToRgb(int val, int val1)
{`enter code here`
double actual = 0.0;
int range = 70000000 - 100000;
actual = data[val, val1];
int main = Convert.ToInt32(255 * actual / range);
string hexR = main.ToString("X2");
int flip = Convert.ToInt32(255 * (1 - (actual / range)));
string hexB = flip.ToString("X2");
string colorValue = "#" + hexR + "00" + hexB;
byte R = Convert.ToByte(colorValue.Substring(1, 2), 16);
byte G = Convert.ToByte(colorValue.Substring(3, 2), 16);
byte B = Convert.ToByte(colorValue.Substring(5, 2), 16);
Color background = Color.FromArgb((byte)255, R, G, B);
return new SolidColorBrush(background);
}
}
very bad performance after i=50 it is very slow and not loading may be performance issue of in line graphs as it is huge number.
Please help if any body can tell improvement or suggests other ways to create Spectrogram in windows store apps 8.1 development.
XAML page
<Page xmlns:Charting="using:WinRTXamlToolkit.Controls.DataVisualization.Charting"
x:Class="MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Spect"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid >
<Grid.Resources>
<Style
x:Key="ColorByPreferenceColumn"
x:Name="abc"
TargetType="Charting:LineDataPoint">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate
TargetType="Charting:LineDataPoint">
<Grid Background="{Binding FavoriteColor}">
<Polygon>
<Polygon.Fill>
<LinearGradientBrush>
<GradientStop Color="#77ffffff" Offset="0"/>
<GradientStop Color="#00ffffff" Offset="1"/>
</LinearGradientBrush>
</Polygon.Fill>
</Polygon>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Charting:Chart x:Name="LineChart" HorizontalAlignment="Left" VerticalAlignment="Top" Width="300" Height="600" Margin="208,107,0,0">
</Charting:Chart>
<Button Content="Data" HorizontalAlignment="Left" Margin="175,31,0,0" VerticalAlignment="Top" Click="Button_Click"/>
</Grid>

How to Change Opacity of outside Rectangle?

In my case i want to change the opacity of the video brush using Rectangle. Rectangle area should have Transparent and out side rectangle should have semi Transparent. I don't know how to do this. I need some sample for this.
Thanks in advance
Edit:
I have tried Grid row and column definition . like this
<Grid Background="Transparent" Name="OuterGrid">
<Grid.RowDefinitions>
<RowDefinition Height="211*"/>
<RowDefinition Height="308"/>
<RowDefinition Height="249*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle
Stroke="Red"
StrokeThickness="4"
Fill="LightGray"
Grid.Row="1"
Grid.Column="1" />
<Rectangle
MouseMove="Rectangle_MouseMove_TopLeft"
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"
MouseLeftButtonUp="Rectangle_MouseLeftButtonUp"
Stroke="Yellow"
Canvas.ZIndex="1"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Height="30"
Width="30"
StrokeThickness="4" Grid.Row="1"
Fill="Red"
Grid.Column="1" />
<Rectangle
MouseMove="Rectangle_MouseMove_TopRight"
Stroke="Yellow"
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"
MouseLeftButtonUp="Rectangle_MouseLeftButtonUp"
Canvas.ZIndex="1"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Height="30"
Width="30"
StrokeThickness="4" Grid.Row="1"
Fill="Red"
Grid.Column="1" />
<Rectangle
MouseMove="Rectangle_MouseMove_BottomLeft"
Stroke="Yellow"
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"
MouseLeftButtonUp="Rectangle_MouseLeftButtonUp"
Canvas.ZIndex="1"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Height="30"
Width="30"
StrokeThickness="4" Grid.Row="1"
Fill="Red"
Grid.Column="1" />
<Rectangle
MouseMove="Rectangle_MouseMove_BottomLeft"
Stroke="Yellow"
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"
MouseLeftButtonUp="Rectangle_MouseLeftButtonUp"
Canvas.ZIndex="1"
HorizontalAlignment="Right"
Width="30"
StrokeThickness="4" Grid.Row="1"
Fill="Red"
Grid.Column="1" Margin="0,278,0,0" />
</Grid>
c#
private void Rectangle_MouseMove_TopLeft(object sender, MouseEventArgs e)
{
if (isMove)
{
Point p = e.GetPosition(this.OuterGrid);
double pX = point.X - p.X;
double pY = point.Y - p.Y;
double w = OuterGrid.ColumnDefinitions.ElementAt(1).ActualWidth + pX;
double h = OuterGrid.RowDefinitions.ElementAt(1).ActualHeight + pY;
//if (pX < w)
//{
// OuterGrid.ColumnDefinitions.ElementAt(1).Width = new GridLength(w + (w - pX), GridUnitType.Pixel);
//}
//else
//{
// OuterGrid.ColumnDefinitions.ElementAt(1).Width = new GridLength(w - (w - pX), GridUnitType.Pixel);
//}
//if (pY < h)
//{
// OuterGrid.RowDefinitions.ElementAt(1).Height = new GridLength(h + (h - pY), GridUnitType.Pixel);
//}
//else
//{
// OuterGrid.RowDefinitions.ElementAt(1).Height = new GridLength(h - (h - pY), GridUnitType.Pixel);
//}
OuterGrid.RowDefinitions.ElementAt(1).Height = new GridLength(h, GridUnitType.Pixel);
OuterGrid.ColumnDefinitions.ElementAt(1).Width = new GridLength(w, GridUnitType.Pixel);
}
}
private void Rectangle_MouseMove_TopRight(object sender, MouseEventArgs e)
{
if (isMove)
{
Point p = e.GetPosition(this.OuterGrid);
double pX = p.X;
double pY = p.Y;
double w = OuterGrid.ColumnDefinitions.ElementAt(1).ActualWidth;
double h = OuterGrid.RowDefinitions.ElementAt(1).ActualHeight;
OuterGrid.RowDefinitions.ElementAt(1).Height = new GridLength(p.Y, GridUnitType.Pixel);
OuterGrid.ColumnDefinitions.ElementAt(1).Width = new GridLength(pX, GridUnitType.Pixel);
}
}
private void Rectangle_MouseMove_BottomLeft(object sender, MouseEventArgs e)
{
if (isMove)
{
Point p = e.GetPosition(this.OuterGrid);
double pX = p.X - point.X;
double pY = p.Y -point.Y;
double w = OuterGrid.ColumnDefinitions.ElementAt(1).ActualWidth + pX;
double h = OuterGrid.RowDefinitions.ElementAt(1).ActualHeight + pY;
OuterGrid.RowDefinitions.ElementAt(1).Height = new GridLength(h, GridUnitType.Pixel);
OuterGrid.ColumnDefinitions.ElementAt(1).Width = new GridLength(w, GridUnitType.Pixel);
}
}
private void Rectangle_MouseMove_BottomRight(object sender, MouseEventArgs e)
{
if (isMove)
{
Point p = e.GetPosition(this.OuterGrid);
double pX = p.X;
double pY = p.Y;
double w = OuterGrid.ColumnDefinitions.ElementAt(1).ActualWidth;
double h = OuterGrid.RowDefinitions.ElementAt(1).ActualHeight;
OuterGrid.RowDefinitions.ElementAt(1).Height = new GridLength(p.Y, GridUnitType.Pixel);
OuterGrid.ColumnDefinitions.ElementAt(1).Width = new GridLength(pX, GridUnitType.Pixel);
}
}
private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
isMove = true;
point = e.GetPosition(this.OuterGrid);
}
private void Rectangle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
isMove = false;
}
I need smooth motion on this.
Pls fine tune this code
I'm not 100% sure of what you want to achieve exactly (e.g. what video brush are you referring to?), but I attempted it anyway.
I'm guessing you want WP 8 not WP 8.1 (based on your original code).
Outside region is darkened while region inside the rectangle remains untouched. I'm not 100% sure if it's possible to invert an element's Clip or OpacityMask, so the way I achieved this is kind of hacky.
Your original code was very buggy, not DRY, and the handles didn't resize properly so I fixed that.
Final result
XAML
<Grid x:Name="LayoutRoot">
<Grid.Background>
<ImageBrush ImageSource="/Assets/Image.jpg" Stretch="None" />
</Grid.Background>
<Grid x:Name="OuterRect">
<Grid.Resources>
<Style x:Key="HandleStyle" TargetType="Rectangle">
<Setter Property="Width" Value="30" />
<Setter Property="Height" Value="30" />
<Setter Property="StrokeThickness" Value="4" />
<Setter Property="Stroke" Value="Red" />
<Setter Property="Fill" Value="Yellow" />
</Style>
</Grid.Resources>
<Rectangle Fill="Black" Opacity="0.6" />
<Grid x:Name="Rect" Width="300" Height="400">
<Rectangle Stroke="Red" StrokeThickness="4">
<Rectangle.Fill>
<ImageBrush ImageSource="/Assets/Image.jpg" Stretch="None" />
</Rectangle.Fill>
</Rectangle>
<Rectangle
x:Name="HandleTopLeft"
Style="{StaticResource HandleStyle}"
MouseMove="Handle_MouseMove"
MouseLeftButtonDown="Handle_MouseLeftButtonDown"
MouseLeftButtonUp="Handle_MouseLeftButtonUp"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
<Rectangle
x:Name="HandleTopRight"
Style="{StaticResource HandleStyle}"
MouseMove="Handle_MouseMove"
MouseLeftButtonDown="Handle_MouseLeftButtonDown"
MouseLeftButtonUp="Handle_MouseLeftButtonUp"
HorizontalAlignment="Right"
VerticalAlignment="Top" />
<Rectangle
x:Name="HandleBottomLeft"
Style="{StaticResource HandleStyle}"
MouseMove="Handle_MouseMove"
MouseLeftButtonDown="Handle_MouseLeftButtonDown"
MouseLeftButtonUp="Handle_MouseLeftButtonUp"
HorizontalAlignment="Left"
VerticalAlignment="Bottom" />
<Rectangle
x:Name="HandleBottomRight"
Style="{StaticResource HandleStyle}"
MouseMove="Handle_MouseMove"
MouseLeftButtonDown="Handle_MouseLeftButtonDown"
MouseLeftButtonUp="Handle_MouseLeftButtonUp"
HorizontalAlignment="Right"
VerticalAlignment="Bottom" />
</Grid>
</Grid>
</Grid>
C# code-behind
const double MIN_RECT_WIDTH = 80;
const double MIN_RECT_HEIGHT = 80;
bool isDragging;
Point startPoint;
Size startSize;
private void Handle_MouseMove(object sender, MouseEventArgs e)
{
if (!isDragging)
return;
var handle = (Rectangle)sender;
var p = e.GetPosition(null);
var deltaX = p.X - startPoint.X;
var deltaY = p.Y - startPoint.Y;
if (handle == HandleTopLeft || handle == HandleBottomLeft) deltaX = -deltaX;
if (handle == HandleTopLeft || handle == HandleTopRight) deltaY = -deltaY;
Rect.Width = Math.Min(OuterRect.ActualWidth, Math.Max(MIN_RECT_WIDTH, startSize.Width + deltaX * 2));
Rect.Height = Math.Min(OuterRect.ActualHeight, Math.Max(MIN_RECT_HEIGHT, startSize.Height + deltaY * 2));
}
private void Handle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var handle = (Rectangle)sender;
handle.CaptureMouse();
isDragging = true;
startPoint = e.GetPosition(null);
startSize = Rect.RenderSize;
}
private void Handle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var handle = (Rectangle)sender;
handle.ReleaseMouseCapture();
isDragging = false;
}

Scaling a 1920 * 1080p photo to be the lock screen image on a 1080p Windows Phone

I want to use the Bing Image of the Day as the background for my app's lock screen image, but I'm having problems getting the image to scale desirably on 1080p devices.
This is an example of a 1080p Bing Image of the Day: http://www.bing.com//az/hprichbg/rb/BeaverMeadow_EN-US12190942812_1920x1080.jpg. It's a 1920 * 1080 photo.
What I do is crop it so that the photo I'm using is 1080 * 1080 pixels, and then create a new lock screen image that's 1080 * 1920. This is the code:
public static void SaveToJpeg(Stream stream)
{
using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream isostream = iso.CreateFile("lockscreen.jpg"))
{
try
{
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(stream);
WriteableBitmap wb = new WriteableBitmap(bitmap);
// Cropping image so that only 1080 out of the 1920 horizontal pixels are used.
wb = CropImage(wb, 1080, 1920, 1080, 1080);
// 1080 * 1920 are the phone's dimesions.
Extensions.SaveJpeg(wb, isostream, 1080, 1920, 0, 100);
isostream.Close();
}
catch( Exception e )
{
}
}
}
}
public static WriteableBitmap CropImage(WriteableBitmap source, int phoneWidth, int phoneHeight,
int width, int height)
{
// Based on the phone's width/height and image's width/height, will determine
// the correct x and y offsets.
int xOffset = 0, yOffset = 0;
if( phoneWidth >= source.PixelWidth )
{
xOffset = 0;
}
else
{
xOffset = source.PixelWidth - phoneWidth;
xOffset = xOffset / 2 + xOffset / 4;
}
if (phoneHeight >= height)
{
yOffset = 0;
}
else
{
yOffset = height - phoneHeight;
yOffset = yOffset / 2;
}
var sourceWidth = source.PixelWidth;
// Get the resultant image as WriteableBitmap with specified size
var result = new WriteableBitmap(width, height);
// Create the array of bytes
for (var x = 0; x <= height - 1; x++)
{
var sourceIndex = xOffset + (yOffset + x) * sourceWidth;
var destinationIndex = x * width;
Array.Copy(source.Pixels, sourceIndex, result.Pixels, destinationIndex, width);
}
return result;
}
Unsurprisingly, given that the Bing image's height is 1080 pixels (and not 1920) this is what the lock screen looks like:
And, yes, the custom user control that the lock screen image is created from has its Grid background image stretched to fill:
<Grid.Background>
<ImageBrush
x:Name="Background"
Stretch="Fill"/>
</Grid.Background>
What do I need to do in order to get the Bing image to elegantly fill the screen? That is, I don't want to disproportionately resize (pixelate) the original image in order for it match a 1080p phone's dimensions.
UPDATE: I found an alternative 1080 x 1920 photo for the Bing image of the day (i.e. with exact dimensions of 1080p phone's lock screen): http://www.bing.com//az/hprichbg/rb/BeaverMeadow_EN-US12190942812_1080x1920.jpg.
However using it doesn't seem to fix the underlying problem (note: I'm not cropping anything from this image, but using this image as it is because the dimensions are perfect). See below:
Okay, this was silly. In the lock screen user control's xaml I just had to increase the height of the Grid's final row:
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="0"/>
<RowDefinition Height="30"/>
<RowDefinition Height="160"/>
<RowDefinition Height="18"/>
<RowDefinition Height="1920"/>
</Grid.RowDefinitions>
It was previously set to 900.

Calling the zoom in and out of context menu from custom button in flex3

I want to call the zoom in and zoom out function of context menu from custom button In adobe flex application.
Code something like this :
onZoomInButtonClick()
{
this.contextMenu.customItems.zoom.doIn();
}
There is (at least to my knowledge) no way for you to access the flash player zoom in/out commands via code.
You can fake it though by doing the following in your document class (top-most display object under stage)
stage.addEventListener(MouseEvent.MOUSE_WHEEL,mouseWheel,true,2); //listen on the capture phase of the event and give a higher priority than default so it reacts before your grid
function mouseWheel(e:MouseEvent):void {
if(!e.ctrlKey) return; //Ctrl has to be pressed or we ignore the wheel
e.stopImmediatePropagation(); //this stops the event from firing on anything else, like your data grid
var tmpScale:Number = scaleX + (e.delta > 0 ? .2 : -.2); //lets zoom in/out in incriments of 20% (.1)
if(tmpScale < 1){ //if the scale is less than one now, lets keep it at 1
tmpScale = 1;
this.scaleX = 1;
this.x = 0;
this.scaleY = 1;
this.y = 0;
return;
}
if(tmpScale > 4){ //lets set the max to 4
tmpScale = 4;
}
scaleAroundMouse(this,tmpScale);
}
function scaleAroundMouse(objectToScale:DisplayObject, scaleAmount:Number, bounds:Rectangle = null):void {
// scaling will be done relatively
var relScaleX:Number = scaleAmount / objectToScale.scaleX;
var relScaleY:Number = scaleAmount / objectToScale.scaleY;
// map vector to centre point within parent scope
var scalePoint:Point = objectToScale.localToGlobal( new Point(objectToScale.mouseX, objectToScale.mouseY));
scalePoint = objectToScale.parent.globalToLocal( scalePoint );
// current registered postion AB
var AB:Point = new Point( objectToScale.x, objectToScale.y );
// CB = AB - scalePoint, objectToScale vector that will scale as it runs from the centre
var CB:Point = AB.subtract( scalePoint );
CB.x *= relScaleX;
CB.y *= relScaleY;
// recaulate AB, objectToScale will be the adjusted position for the clip
AB = scalePoint.add( CB );
// set actual properties
if(bounds){
var limits:Rectangle = new Rectangle(
bounds.x + (bounds.width - (objectToScale.width * relScaleX)),
bounds.y + (bounds.height - (objectToScale.height * relScaleY)),
(objectToScale.width * relScaleX) - bounds.width,
(objectToScale.height * relScaleY) - bounds.height
);
if(AB.x < limits.x) AB.x = limits.x;
if(AB.x > limits.x + limits.width) AB.x = limits.x + limits.width;
if(AB.y < limits.y) AB.y = limits.y;
if(AB.y > limits.y + limits.height) AB.y = limits.y + limits.height;
}
objectToScale.scaleX = scaleAmount;
objectToScale.scaleY = scaleAmount;
objectToScale.x = AB.x;
objectToScale.y = AB.y;
}
Ok, advancedatagrid may listen keyboard events, when ctrl key down - listen mousewheel events and change scale, see example:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
protected function doMouseWheel(evt:MouseEvent):void
{
scaleX = scaleY += evt.delta * 0.1;
}
protected function adg_keyDownHandler(event:KeyboardEvent):void
{
if (event.ctrlKey)
{
systemManager.addEventListener(MouseEvent.MOUSE_WHEEL, doMouseWheel);
}
}
protected function adg_keyUpHandler(event:KeyboardEvent):void
{
if (!event.ctrlKey)
{
systemManager.removeEventListener(MouseEvent.MOUSE_WHEEL, doMouseWheel);
}
}
]]>
</fx:Script>
<mx:AdvancedDataGrid id="adg" keyDown="adg_keyDownHandler(event)" keyUp="adg_keyUpHandler(event)"
horizontalCenter="0" verticalCenter="0">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="#label"/>
<mx:AdvancedDataGridColumn dataField="#data" />
</mx:columns>
<mx:dataProvider>
<s:XMLListCollection id="dp">
<s:source>
<fx:XMLList>
<product label="Product 1" data="3" />
<product label="Product 2" data="1" />
<product label="Product 3" data="4" />
<product label="Product 4" data="1" />
<product label="Product 5" data="5" />
<product label="Product 6" data="9" />
</fx:XMLList>
</s:source>
</s:XMLListCollection>
</mx:dataProvider>
</mx:AdvancedDataGrid>
</s:Application>
In order to zoom in/out a vector graphics, you plainly change its scaleX and scaleY properties uniformly. The vector renderer of Flash will draw you a correct picture. In order to zoom in on a Bitmap and not get pixelated output, you have to convert it into a vector graphics object like this:
var sh:Shape=new Shape();
sh.graphics.beginBitmapFill(yourBitmap);
sh.graphics.lineStyle(0,0,0); // to not have border lines
sh.graphics.drawRect(0,0,yourBitmap.width,yourBitmap.height);
sh.graphics.endFill();
And then adjusting scaleX and scaleY of that shape will produce interpolated output as you seemingly want.

Silverlight ScrollViewer not updating after zoom

I have a Silverlight grid with a bunch of content in it (rectangles, textBlocks, etc.) which represents content in a room. Because it gets pretty complex, I decided I needed an ability to "zoom-in" on the grid. I found some good code to do that, but the problem is that after zooming the grids associated ScrollViewer doesn't scroll the full distance down or to the right. How can I force it to update so that I can scroll to the bottom and all the way to the right?
If it helps, here's the code to permit zooming of my Grid:
var style = new Style(typeof(Grid));
var scale = new ScaleTransform();
scale.CenterX = .5;
scale.CenterY =.5;
scale.ScaleX = Scale;
scale.ScaleY = Scale;
var rs = new Setter();
rs.Property = DataGridCell.RenderTransformProperty;
rs.Value = scale;
style.Setters.Add(rs);
OtdrPatchLocationGrid.Style = style;
and here is the XAML that shows the grid and the scroll viewer
<ScrollViewer Name="scViewer" Grid.Row="1" Visibility="Visible" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
<Grid x:Name="OtdrPatchLocationGrid" MinHeight="350" VerticalAlignment="Stretch" Background="Yellow" Grid.Row="1" Grid.Column="0" Margin="0" MouseDown="OtdrRackViewer_MouseDown">
</Grid>
</ScrollViewer>
I'm working on the same issue now,
the ScrollViewer is affected only by the change in Width or Height,
so to fix the problem, you have to do as the following:
suppose we got the Grid or Canvas named (ZoomCanvas)
in the code behind:
double initialCanvasHeight;
double initialCanvasWidth;
public void MainPage() //As the Constructor
{
initialCanvasHeight = ZoomCanvas.Height;
initialCanvasWidth = ZoomCanvas.Width;
}
ZoomCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
/*Assuming you have the scaling code here and the object CanvasScale is used to scale the canvas*/
foreach (var node in ZoomCanvas)
{
var nodeTop = Canvas.GetTop(node);
var nodeLeft = Canvas.GetLeft(node);
if(mostTopValue < nodeTop)
mostTopValue = nodeTop;
if(mostLeftValue < nodeLeft)
mostLeftValue = nodeLeft;
var desiredHeight = (mostTopValue + NodeHeight)*canvasScale.ScaleY;
var desiredWidth = (mostLeftValue + NodeWidth) * canvasScale.ScaleX;
if (desiredHeight > canvasInitialHeight)
{
while (heightToIncrease < desiredHeight)
heightToIncrease += 10;
ZoomCanvas.Height = heightToIncrease;
}
else
while (ZoomCanvas.Height > canvasInitialHeight)
ZoomCanvas.Height -= 10;
if (desiredWidth > canvasInitialWidth)
{
while (widthToIncrease < desiredWidth)
widthToIncrease += 10;
ZoomCanvas.Width = widthToIncrease;
}
else while (ZoomCanvas.Height > canvasInitialHeight)
ZoomCanvas.Width -= 10;
}
scrollViewer.UpdateLayout();
}