285 lines
9.4 KiB
C#
285 lines
9.4 KiB
C#
/*************************************************************************************
|
|
|
|
Extended WPF Toolkit
|
|
|
|
Copyright (C) 2007-2013 Xceed Software Inc.
|
|
|
|
This program is provided to you under the terms of the Microsoft Public
|
|
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
|
|
|
|
For more features, controls, and fast professional support,
|
|
pick up the Plus Edition at http://xceed.com/wpf_toolkit
|
|
|
|
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|
|
|
***********************************************************************************/
|
|
|
|
using System;
|
|
using System.Windows;
|
|
using System.Windows.Media;
|
|
using Xceed.Wpf.Toolkit.Core.Utilities;
|
|
|
|
namespace Xceed.Wpf.Toolkit.Zoombox
|
|
{
|
|
public class ZoomboxViewFinderDisplay : FrameworkElement
|
|
{
|
|
#region Constructors
|
|
|
|
static ZoomboxViewFinderDisplay()
|
|
{
|
|
ZoomboxViewFinderDisplay.DefaultStyleKeyProperty.OverrideMetadata( typeof( ZoomboxViewFinderDisplay ), new FrameworkPropertyMetadata( typeof( ZoomboxViewFinderDisplay ) ) );
|
|
}
|
|
|
|
public ZoomboxViewFinderDisplay()
|
|
{
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Background Property
|
|
|
|
public static readonly DependencyProperty BackgroundProperty =
|
|
DependencyProperty.Register( "Background", typeof( Brush ), typeof( ZoomboxViewFinderDisplay ),
|
|
new FrameworkPropertyMetadata( new SolidColorBrush( Color.FromArgb( 0xC0, 0xFF, 0xFF, 0xFF ) ), FrameworkPropertyMetadataOptions.AffectsRender ) );
|
|
|
|
public Brush Background
|
|
{
|
|
get
|
|
{
|
|
return ( Brush )this.GetValue( ZoomboxViewFinderDisplay.BackgroundProperty );
|
|
}
|
|
set
|
|
{
|
|
this.SetValue( ZoomboxViewFinderDisplay.BackgroundProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ContentBounds Property
|
|
|
|
private static readonly DependencyPropertyKey ContentBoundsPropertyKey =
|
|
DependencyProperty.RegisterReadOnly( "ContentBounds", typeof( Rect ), typeof( ZoomboxViewFinderDisplay ),
|
|
new FrameworkPropertyMetadata( ( Rect )Rect.Empty, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender ) );
|
|
|
|
public static readonly DependencyProperty ContentBoundsProperty = ZoomboxViewFinderDisplay.ContentBoundsPropertyKey.DependencyProperty;
|
|
|
|
internal Rect ContentBounds
|
|
{
|
|
get
|
|
{
|
|
return ( Rect )this.GetValue( ZoomboxViewFinderDisplay.ContentBoundsProperty );
|
|
}
|
|
set
|
|
{
|
|
this.SetValue( ZoomboxViewFinderDisplay.ContentBoundsPropertyKey, value );
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ShadowBrush Property
|
|
|
|
public static readonly DependencyProperty ShadowBrushProperty =
|
|
DependencyProperty.Register( "ShadowBrush", typeof( Brush ), typeof( ZoomboxViewFinderDisplay ),
|
|
new FrameworkPropertyMetadata( new SolidColorBrush( Color.FromArgb( 0x80, 0xFF, 0xFF, 0xFF ) ), FrameworkPropertyMetadataOptions.AffectsRender ) );
|
|
|
|
public Brush ShadowBrush
|
|
{
|
|
get
|
|
{
|
|
return ( Brush )this.GetValue( ZoomboxViewFinderDisplay.ShadowBrushProperty );
|
|
}
|
|
set
|
|
{
|
|
this.SetValue( ZoomboxViewFinderDisplay.ShadowBrushProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ViewportBrush Property
|
|
|
|
public static readonly DependencyProperty ViewportBrushProperty =
|
|
DependencyProperty.Register( "ViewportBrush", typeof( Brush ), typeof( ZoomboxViewFinderDisplay ),
|
|
new FrameworkPropertyMetadata( Brushes.Transparent, FrameworkPropertyMetadataOptions.AffectsRender ) );
|
|
|
|
public Brush ViewportBrush
|
|
{
|
|
get
|
|
{
|
|
return ( Brush )this.GetValue( ZoomboxViewFinderDisplay.ViewportBrushProperty );
|
|
}
|
|
set
|
|
{
|
|
this.SetValue( ZoomboxViewFinderDisplay.ViewportBrushProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ViewportPen Property
|
|
|
|
public static readonly DependencyProperty ViewportPenProperty =
|
|
DependencyProperty.Register( "ViewportPen", typeof( Pen ), typeof( ZoomboxViewFinderDisplay ),
|
|
new FrameworkPropertyMetadata( new Pen( new SolidColorBrush( Color.FromArgb( 0x80, 0x00, 0x00, 0x00 ) ), 1d ), FrameworkPropertyMetadataOptions.AffectsRender ) );
|
|
|
|
public Pen ViewportPen
|
|
{
|
|
get
|
|
{
|
|
return ( Pen )this.GetValue( ZoomboxViewFinderDisplay.ViewportPenProperty );
|
|
}
|
|
set
|
|
{
|
|
this.SetValue( ZoomboxViewFinderDisplay.ViewportPenProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ViewportRect Property
|
|
|
|
public static readonly DependencyProperty ViewportRectProperty =
|
|
DependencyProperty.Register( "ViewportRect", typeof( Rect ), typeof( ZoomboxViewFinderDisplay ),
|
|
new FrameworkPropertyMetadata( Rect.Empty, FrameworkPropertyMetadataOptions.AffectsRender ) );
|
|
|
|
public Rect ViewportRect
|
|
{
|
|
get
|
|
{
|
|
return ( Rect )this.GetValue( ZoomboxViewFinderDisplay.ViewportRectProperty );
|
|
}
|
|
set
|
|
{
|
|
this.SetValue( ZoomboxViewFinderDisplay.ViewportRectProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region VisualBrush Property
|
|
|
|
private static readonly DependencyPropertyKey VisualBrushPropertyKey =
|
|
DependencyProperty.RegisterReadOnly( "VisualBrush", typeof( VisualBrush ), typeof( ZoomboxViewFinderDisplay ),
|
|
new FrameworkPropertyMetadata( ( VisualBrush )null ) );
|
|
|
|
public static readonly DependencyProperty VisualBrushProperty = ZoomboxViewFinderDisplay.VisualBrushPropertyKey.DependencyProperty;
|
|
|
|
internal VisualBrush VisualBrush
|
|
{
|
|
get
|
|
{
|
|
return ( VisualBrush )this.GetValue( ZoomboxViewFinderDisplay.VisualBrushProperty );
|
|
}
|
|
set
|
|
{
|
|
this.SetValue( ZoomboxViewFinderDisplay.VisualBrushPropertyKey, value );
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region AvailableSize Internal Property
|
|
|
|
internal Size AvailableSize
|
|
{
|
|
get
|
|
{
|
|
return _availableSize;
|
|
}
|
|
}
|
|
|
|
private Size _availableSize = Size.Empty;
|
|
|
|
#endregion
|
|
|
|
#region Scale Internal Property
|
|
|
|
internal double Scale
|
|
{
|
|
get
|
|
{
|
|
return _scale;
|
|
}
|
|
set
|
|
{
|
|
_scale = value;
|
|
}
|
|
}
|
|
|
|
private double _scale = 1d;
|
|
|
|
#endregion
|
|
|
|
protected override Size ArrangeOverride( Size finalSize )
|
|
{
|
|
// Note that we do not call the Arrange method on any children
|
|
// because a ViewFinderDisplay has no children
|
|
|
|
// the control's RenderSize should always match its DesiredSize
|
|
return this.DesiredSize;
|
|
}
|
|
|
|
protected override Size MeasureOverride( Size availableSize )
|
|
{
|
|
// Note that we do not call the Measure method on any children
|
|
// because a ViewFinderDisplay has no children. It is merely used
|
|
// as a surface for the view finder's VisualBrush.
|
|
|
|
// store the available size for use by the Zoombox control
|
|
_availableSize = availableSize;
|
|
|
|
// Simulate size-to-content for the display panel by ensuring a width and height
|
|
// based on the content bounds. Otherwise, the display panel may have no size, since it doesn't
|
|
// contain content.
|
|
double width = DoubleHelper.IsNaN( this.ContentBounds.Width ) ? 0 : Math.Max( 0, this.ContentBounds.Width );
|
|
double height = DoubleHelper.IsNaN( this.ContentBounds.Height ) ? 0 : Math.Max( 0, this.ContentBounds.Height );
|
|
Size displayPanelSize = new Size( width, height );
|
|
|
|
// Now ensure that the result fits within the available size while maintaining
|
|
// the width/height ratio of the content bounds
|
|
if( displayPanelSize.Width > availableSize.Width || displayPanelSize.Height > availableSize.Height )
|
|
{
|
|
double aspectX = availableSize.Width / displayPanelSize.Width;
|
|
double aspectY = availableSize.Height / displayPanelSize.Height;
|
|
double scale = ( aspectX < aspectY ) ? aspectX : aspectY;
|
|
displayPanelSize = new Size( displayPanelSize.Width * scale, displayPanelSize.Height * scale );
|
|
}
|
|
|
|
return displayPanelSize;
|
|
}
|
|
|
|
protected override void OnRender( DrawingContext dc )
|
|
{
|
|
base.OnRender( dc );
|
|
|
|
dc.DrawRectangle( this.Background, null, this.ContentBounds );
|
|
|
|
dc.DrawRectangle( this.VisualBrush, null, this.ContentBounds );
|
|
|
|
if( this.ViewportRect.IntersectsWith( new Rect( this.RenderSize ) ) )
|
|
{
|
|
// draw shadow rectangles over the non-viewport regions
|
|
Rect r1 = new Rect( new Point( 0, 0 ), new Size( this.RenderSize.Width, Math.Max( 0, this.ViewportRect.Top ) ) );
|
|
Rect r2 = new Rect( new Point( 0, this.ViewportRect.Top ), new Size( Math.Max( 0, this.ViewportRect.Left ), this.ViewportRect.Height ) );
|
|
Rect r3 = new Rect( new Point( this.ViewportRect.Right, this.ViewportRect.Top ), new Size( Math.Max( 0, this.RenderSize.Width - this.ViewportRect.Right ), this.ViewportRect.Height ) );
|
|
Rect r4 = new Rect( new Point( 0, this.ViewportRect.Bottom ), new Size( this.RenderSize.Width, Math.Max( 0, this.RenderSize.Height - this.ViewportRect.Bottom ) ) );
|
|
dc.DrawRectangle( this.ShadowBrush, null, r1 );
|
|
dc.DrawRectangle( this.ShadowBrush, null, r2 );
|
|
dc.DrawRectangle( this.ShadowBrush, null, r3 );
|
|
dc.DrawRectangle( this.ShadowBrush, null, r4 );
|
|
|
|
// draw the rectangle around the viewport region
|
|
dc.DrawRectangle( this.ViewportBrush, this.ViewportPen, this.ViewportRect );
|
|
}
|
|
else
|
|
{
|
|
// if no part of the Rect is visible, just draw a
|
|
// shadow over the entire content bounds
|
|
dc.DrawRectangle( this.ShadowBrush, null, new Rect( this.RenderSize ) );
|
|
}
|
|
}
|
|
}
|
|
}
|