private void ScaleVisual3D(PhotoStackViewVisual3D visual3D, double aspectRatio) { double scaleX, scaleY; // adjust scale on mesh scaleY = 1; scaleX = MESH_HEIGHT * aspectRatio; // fit within requested box as well double scaleFactor = 1; if (aspectRatio > 1) { scaleFactor = Width / (MESH_WIDTH * scaleX); } else { scaleFactor = Height / (MESH_HEIGHT * scaleY); } scaleX *= scaleFactor; scaleY *= scaleFactor; visual3D.Content.Transform = new ScaleTransform3D(scaleX, scaleY, scaleX); }
protected override InteractiveVisual3D GetVisual3DRepresentation(object o) { FlickrPhoto photo = (FlickrPhoto)o; // create the visual3D to return PhotoStackViewVisual3D visual3D = new PhotoStackViewVisual3D(photo); // set up the material MaterialGroup material = new MaterialGroup(); DiffuseMaterial interactiveMaterial = new DiffuseMaterial(); interactiveMaterial.SetValue(InteractiveVisual3D.IsInteractiveMaterialProperty, true); material.Children.Add(interactiveMaterial); material.Children.Add(new SpecularMaterial(Brushes.White, 40)); visual3D.Material = material; visual3D.Geometry = meshGeometry; PictureComment xamlRep = GetXamlRepresentation(); visual3D.Visual = xamlRep; xamlRep.pictureVisual.curvatureSlider.ValueChanged += new RoutedPropertyChangedEventHandler<double>(delegate(object sender, RoutedPropertyChangedEventArgs<double> e) { visual3D.Geometry = CreateGeometry(e.NewValue); }); xamlRep.pictureVisual.closeButton.Click += new RoutedEventHandler( delegate(object sender, RoutedEventArgs e) { RemoveItem(photo); }); xamlRep.pictureVisual.geoButton.Click += new RoutedEventHandler( delegate(object sender, RoutedEventArgs e) { XmlDocument doc = new XmlDocument(); doc.Load(new StringReader(photo.Info)); XmlNode node = doc.SelectSingleNode("/photo/location"); GeoLocationSelected(Double.Parse(node.Attributes["longitude"].Value), Double.Parse(node.Attributes["latitude"].Value), photo); }); xamlRep.pictureVisual.blogButton.Click += new RoutedEventHandler( delegate(object sender, RoutedEventArgs e) { BlogRequested(photo); }); // if there is an authorized user - set it up so they can comment on photos if (Flickr.CurrAuthorizedUser != null) { xamlRep.submitCommentButton.IsEnabled = true; xamlRep.submitCommentButton.Click += new RoutedEventHandler( delegate(object sender, RoutedEventArgs e) { Flickr.AsynchPostComments(xamlRep.textBox1.Text, photo, Flickr.CurrAuthorizedUser, Dispatcher, delegate(object result) { if ((bool)result) { Flickr.AsynchGetPhotoComments(photo, visual3D.Dispatcher, delegate(object resultData) { PhotoCommentsReceived(xamlRep, (string)resultData); }); } }); }); } // make an asynch call to flickr to get the photo information we're interested in if (photo != null) { BitmapImage b = new BitmapImage(new Uri(photo.URL_Medium)); if (b.IsDownloading) { // use the small image until the large is ready if (photo.SmallImage != null) { xamlRep.UpdateImage(photo.SmallImage); } b.DownloadCompleted += delegate(object sender, EventArgs e) { xamlRep.UpdateImage(b); ScaleVisual3D(visual3D, xamlRep.Width / (2 * xamlRep.Height)); }; } else { xamlRep.UpdateImage(b); } } // request all sort of information about the photo Flickr.AsynchGetPhotoComments(photo, visual3D.Dispatcher, delegate(object resultData) { PhotoCommentsReceived(xamlRep, (string)resultData); }); if (photo.Info == null) { Flickr.AsynchGetPhotoInfo(photo, visual3D.Dispatcher, delegate(object resultData) { PhotoInfoReceived(xamlRep, (string)resultData); }); } else { PhotoInfoReceived(xamlRep, photo.Info); } ScaleVisual3D(visual3D, xamlRep.Width / (2 * xamlRep.Height)); // return the visual w/o the bitmap yet return visual3D; }