Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Themes / Shared / Microsoft / Windows / Themes / BulletChrome.cs / 1 / BulletChrome.cs
//---------------------------------------------------------------------------- // File: BulletChrome.cs // // Description: // Implementation of CheckBox and RadioButtons in Luna and Royale. // // Copyright (C) 2006 by Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System.Windows.Shapes; using System.Windows.Controls; using System.Diagnostics; using System.Threading; using System.Windows; using System.Windows.Media; using MS.Internal; using System; namespace Microsoft.Windows.Themes { public sealed class BulletChrome : FrameworkElement { #region Constructors static BulletChrome() { IsEnabledProperty.OverrideMetadata(typeof(BulletChrome), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender)); } ////// Instantiates a new instance of a BulletChrome with no parent element. /// public BulletChrome() { } #endregion Constructors #region Dynamic Properties ////// DependencyProperty for public static readonly DependencyProperty BackgroundProperty = Control.BackgroundProperty.AddOwner( typeof(BulletChrome), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// The Background property defines the brush used to fill the background of the button. /// public Brush Background { get { return (Brush) GetValue(BackgroundProperty); } set { SetValue(BackgroundProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty BorderBrushProperty = System.Windows.Controls.Border.BorderBrushProperty.AddOwner( typeof(BulletChrome), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// The BorderBrush property defines the brush used to draw the outer border. /// public Brush BorderBrush { get { return (Brush) GetValue(BorderBrushProperty); } set { SetValue(BorderBrushProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty BorderThicknessProperty = System.Windows.Controls.Border.BorderThicknessProperty.AddOwner(typeof(BulletChrome)); ///property. /// /// The BorderThickness property defines the Thickness used to draw the outer border. /// public Thickness BorderThickness { get { return (Thickness)GetValue(BorderThicknessProperty); } set { SetValue(BorderThicknessProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty RenderMouseOverProperty = DependencyProperty.Register("RenderMouseOver", typeof(bool), typeof(BulletChrome), new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// When true the chrome renders with a mouse over look. /// public bool RenderMouseOver { get { return (bool)GetValue(RenderMouseOverProperty); } set { SetValue(RenderMouseOverProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty RenderPressedProperty = DependencyProperty.Register("RenderPressed", typeof(bool), typeof(BulletChrome), new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// When true the chrome renders with a pressed look. /// public bool RenderPressed { get { return (bool)GetValue(RenderPressedProperty); } set { SetValue(RenderPressedProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register("IsChecked", typeof(bool?), typeof(BulletChrome), new FrameworkPropertyMetadata( ((bool?)false), FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// When true, the left border will have round corners, otherwise they will be square. /// public bool? IsChecked { get { return (bool?)GetValue(IsCheckedProperty); } set { SetValue(IsCheckedProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty IsRoundProperty = DependencyProperty.Register("IsRound", typeof(bool), typeof(BulletChrome), new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// When true, the left border will have round corners, otherwise they will be square. /// public bool IsRound { get { return (bool)GetValue(IsRoundProperty); } set { SetValue(IsRoundProperty, value); } } #endregion Dynamic Properties #region Protected Methods ////// Updates DesiredSize of the BulletChrome. Called by parent UIElement. This is the first pass of layout. /// /// Available size is an "upper limit" that the return value should not exceed. ///The BulletChrome's desired size. protected override Size MeasureOverride(Size availableSize) { Thickness thickness = BorderThickness; bool isRound = IsRound; double borderX = isRound ? 2.0 : thickness.Left + thickness.Right; double borderY = isRound ? 2.0 : thickness.Top + thickness.Bottom; Size desired; desired = new Size(Math.Min(11.0 + borderX, availableSize.Width), Math.Min(11.0 + borderY, availableSize.Height)); return desired; } ////// Render callback. /// protected override void OnRender(DrawingContext drawingContext) { Thickness thickness = BorderThickness; bool isUnitThickness = thickness.Left == 1.0 && thickness.Right == 1.0 && thickness.Top == 1.0 && thickness.Bottom == 1.0; Rect bounds = new Rect(0, 0, ActualWidth, ActualHeight); Rect innerBounds = bounds; // Apply BorderThickness to Checkbox only if (!IsRound) { innerBounds = new Rect(thickness.Left, thickness.Top, Math.Max(0, bounds.Width - thickness.Left - thickness.Right), Math.Max(0, bounds.Height - thickness.Top - thickness.Bottom)); } // Draw Background DrawBackground(drawingContext, ref innerBounds); // Draw innerborder and fill with inner fill DrawHighlight(drawingContext, ref innerBounds); DrawGlyph(drawingContext, ref innerBounds, isUnitThickness); // Draw outer border DrawBorder(drawingContext, ref bounds, thickness, isUnitThickness); } private void DrawBackground(DrawingContext dc, ref Rect bounds) { Brush fill = BackgroundBrush; if (fill != null && (bounds.Width > 2.0) && (bounds.Height > 2.0)) { if (!IsRound) { // Draw Background dc.DrawRectangle(fill, null, bounds); } else { double centerX = bounds.Width * 0.5; double centerY = bounds.Height * 0.5; // Draw Background dc.DrawEllipse(fill, null, new Point(centerX, centerY), centerX - 1, centerY - 1); } } } // Draw the inner border private void DrawHighlight(DrawingContext dc, ref Rect bounds) { Pen highlightPen = HighlightPen; if (highlightPen != null && (bounds.Width >= 4.0) && (bounds.Height >= 4.0)) { if (!IsRound) { dc.DrawRectangle(null, highlightPen, new Rect(bounds.Left + 1.0, bounds.Top + 1.0, bounds.Width - 2.0, bounds.Height - 2.0)); } else { double centerX = bounds.Width * 0.5; double centerY = bounds.Height * 0.5; dc.DrawEllipse(null, highlightPen, new Point(centerX, centerY), centerX - 2, centerY - 2); } } } // Draw the CheckMark or Dot private void DrawGlyph(DrawingContext dc, ref Rect bounds, bool isUnitThickness) { Brush glyphFill = GlyphFill; if (glyphFill != null && (bounds.Width > 4.0) && (bounds.Height > 4.0)) { if (!IsRound) { if (IsChecked == true) { // Translate Glyph if not 1px borders if (!isUnitThickness) { dc.PushTransform(new TranslateTransform(bounds.Left - 1.0, bounds.Top - 1.0)); } // Need to reverse Checkbox in RTL so it draws to screen the same as LTR if (FlowDirection == FlowDirection.RightToLeft) { dc.PushTransform(new ScaleTransform(-1.0, 1.0, 6.5, 0)); } dc.DrawGeometry(glyphFill, null, CheckMarkGeometry); if (FlowDirection == FlowDirection.RightToLeft) { dc.Pop(); } if (!isUnitThickness) { dc.Pop(); } } else if (IsChecked == null) { dc.DrawRectangle(glyphFill, null, new Rect(bounds.Left + 2, bounds.Top + 2, bounds.Width - 4.0, bounds.Height - 4.0)); } } else { if ((bounds.Width > 8.0) && (bounds.Height > 8.0)) { double centerX = bounds.Width * 0.5; double centerY = bounds.Height * 0.5; dc.DrawEllipse(glyphFill, null, new Point(centerX, centerY), centerX - 4, centerY - 4); } } } } // Draw the main border private void DrawBorder(DrawingContext dc, ref Rect bounds, Thickness thickness, bool isUnitThickness) { if ((bounds.Width >= 5.0) && (bounds.Height >= 5.0)) { if (!IsRound) { if (isUnitThickness) { Pen borderPen = BorderPen; if (borderPen != null) { Rect rect = new Rect(bounds.Left + 0.5, bounds.Top + 0.5, bounds.Width - 1.0, bounds.Height - 1.0); dc.DrawRectangle(null, borderPen, rect); } } else { Brush borderBrush = Border; if (borderBrush != null) { dc.DrawGeometry(borderBrush, null, GenerateBorderGeometry(bounds, thickness)); } } } else // IsRound == true { Pen borderPen = BorderPen; if (borderPen != null) { double centerX = bounds.Width * 0.5; double centerY = bounds.Height * 0.5; dc.DrawEllipse(null, borderPen, new Point(centerX, centerY), centerX - 0.5, centerY - 0.5); } } } } private static Pen GetBorderPen(Brush border) { Pen pen = null; if (border != null) { if (_commonBorderPen == null) // Common case, if non-null, avoid the lock { lock (_resourceAccess) // If non-null, lock to create the pen for thread safety { if (_commonBorderPen == null) // Check again in case _pen was created within the last line { // Assume that the first render of Button uses the most common brush for the app. // This breaks down if (a) the first Button is disabled, (b) the first Button is // customized, or (c) BulletChrome becomes more broadly used than just on Button. // // If these cons sufficiently weaken the effectiveness of this cache, then we need // to build a larger brush-to-pen mapping cache. // If the brush is not already frozen, we need to create our own // copy. Otherwise we will inadvertently freeze the user's // BorderBrush when we freeze the pen below. if (!border.IsFrozen && border.CanFreeze) { border = border.Clone(); border.Freeze(); } Pen commonPen = new Pen(border, 1); if (commonPen.CanFreeze) { // Only save frozen pens, some brushes such as VisualBrush // can not be frozen commonPen.Freeze(); _commonBorderPen = commonPen; } } } } if (_commonBorderPen != null && border == _commonBorderPen.Brush) { pen = _commonBorderPen; } else { if (!border.IsFrozen && border.CanFreeze) { border = border.Clone(); border.Freeze(); } pen = new Pen(border, 1); if (pen.CanFreeze) { pen.Freeze(); } } } return pen; } #endregion #region Private Properties // // This property // 1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject // 2. This is a performance optimization // internal override int EffectiveValuesInitialSize { get { return 9; } } /// Helper to deflate rectangle by thickness private static Rect HelperDeflateRect(Rect rt, Thickness thick) { return new Rect(rt.Left + thick.Left, rt.Top + thick.Top, Math.Max(0.0, rt.Width - thick.Left - thick.Right), Math.Max(0.0, rt.Height - thick.Top - thick.Bottom)); } // Creates a rectangle figure private static PathFigure GenerateRectFigure(Rect rect) { PathFigure figure = new PathFigure(); figure.StartPoint = rect.TopLeft; figure.Segments.Add(new LineSegment(rect.TopRight, true)); figure.Segments.Add(new LineSegment(rect.BottomRight, true)); figure.Segments.Add(new LineSegment(rect.BottomLeft, true)); figure.IsClosed = true; figure.Freeze(); return figure; } // Creates a border geometry used to render complex border brushes private static Geometry GenerateBorderGeometry(Rect rect, Thickness borderThickness) { PathGeometry geometry = new PathGeometry(); // Add outer rectangle figure geometry.Figures.Add(GenerateRectFigure(rect)); // Subtract inner rectangle figure geometry.Figures.Add(GenerateRectFigure(HelperDeflateRect(rect, borderThickness))); geometry.Freeze(); return geometry; } private static Geometry CheckMarkGeometry { get { if (_checkMarkGeometry == null) { lock (_resourceAccess) { if (_checkMarkGeometry == null) { StreamGeometry geometry = new StreamGeometry(); StreamGeometryContext sgc = geometry.Open(); sgc.BeginFigure(new Point(3, 5.0), true, true); sgc.LineTo(new Point(3, 7.8), false, false); sgc.LineTo(new Point(5.5, 10.4), false, false); sgc.LineTo(new Point(10.1, 5.8), false, false); sgc.LineTo(new Point(10.1, 3), false, false); sgc.LineTo(new Point(5.5, 7.6), false, false); sgc.Close(); geometry.Freeze(); _checkMarkGeometry = geometry; } } } return _checkMarkGeometry; } } private static SolidColorBrush CommonDisabledGlyphFill { get { return CommonDisabledBorder; } } private static SolidColorBrush CommonCheckMarkFill { get { if (_commonCheckMarkFill == null) { lock (_resourceAccess) { if (_commonCheckMarkFill == null) { SolidColorBrush temp = new SolidColorBrush(Color.FromRgb(0x21, 0xA1, 0x21)); temp.Freeze(); _commonCheckMarkFill = temp; } } } return _commonCheckMarkFill; } } private static SolidColorBrush CommonCheckMarkPressedFill { get { if (_commonCheckMarkPressedFill == null) { lock (_resourceAccess) { if (_commonCheckMarkPressedFill == null) { SolidColorBrush temp = new SolidColorBrush(Color.FromRgb(0x1A, 0x7E, 0x18)); temp.Freeze(); _commonCheckMarkPressedFill = temp; } } } return _commonCheckMarkPressedFill; } } private static LinearGradientBrush CommonRadioButtonGlyphFill { get { if (_commonRadioButtonGlyphFill == null) { lock (_resourceAccess) { if (_commonRadioButtonGlyphFill == null) { LinearGradientBrush temp = new LinearGradientBrush(); temp.StartPoint = new Point(); temp.EndPoint = new Point(1, 1); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0x60, 0xCF, 0x5D), 0)); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0xAC, 0xEF, 0xAA), 0.302469134)); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0x13, 0x92, 0x10), 1)); temp.Freeze(); _commonRadioButtonGlyphFill = temp; } } } return _commonRadioButtonGlyphFill; } } private static LinearGradientBrush CommonPressedBackground { get { if (_commonPressedBackground == null) { lock (_resourceAccess) { if (_commonPressedBackground == null) { LinearGradientBrush temp = new LinearGradientBrush(); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0xB2, 0xB2, 0xA9), 0)); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0xEB, 0xEA, 0xDA), 1)); temp.Freeze(); _commonPressedBackground = temp; } } } return _commonPressedBackground; } } private static SolidColorBrush CommonDisabledBackground { get { return Brushes.White; } } private static SolidColorBrush CommonDisabledBorder { get { if (_commonDisabledBorder == null) { lock (_resourceAccess) { if (_commonDisabledBorder == null) { SolidColorBrush temp = new SolidColorBrush(Color.FromRgb(0xCA, 0xC8, 0xBB)); temp.Freeze(); _commonDisabledBorder = temp; } } } return _commonDisabledBorder; } } private Brush Border { get { if (!IsEnabled) { return CommonDisabledBorder; } return BorderBrush; } } private static Pen CommonDisabledBorderPen { get { if (_commonDisabledBorderPen == null) { lock (_resourceAccess) { if (_commonDisabledBorderPen == null) { Pen temp = new Pen(); temp.Thickness = 1; temp.Brush = CommonDisabledBorder; temp.Freeze(); _commonDisabledBorderPen = temp; } } } return _commonDisabledBorderPen; } } private static Pen CommonCheckBoxHoverHighlightPen { get { if (_commonCheckBoxHoverHighlightPen == null) { lock (_resourceAccess) { if (_commonCheckBoxHoverHighlightPen == null) { Pen temp = new Pen(); temp.Thickness = 2; LinearGradientBrush brush = new LinearGradientBrush(); brush.StartPoint = new Point(0, 0); brush.EndPoint = new Point(1, 1); brush.GradientStops.Add(new GradientStop(Color.FromRgb(0xFF, 0xF0, 0xCF), 0)); brush.GradientStops.Add(new GradientStop(Color.FromRgb(0xF8, 0xB3, 0x30), 1)); temp.Brush = brush; temp.Freeze(); _commonCheckBoxHoverHighlightPen = temp; } } } return _commonCheckBoxHoverHighlightPen; } } private static Pen CommonRadioButtonHoverHighlightPen { get { if (_commonRadioButtonHoverHighlightPen == null) { lock (_resourceAccess) { if (_commonRadioButtonHoverHighlightPen == null) { Pen temp = new Pen(); temp.Thickness = 2; LinearGradientBrush brush = new LinearGradientBrush(); brush.StartPoint = new Point(0, 0); brush.EndPoint = new Point(1, 1); brush.GradientStops.Add(new GradientStop(Color.FromRgb(0xFE, 0xDF, 0x9C), 0)); brush.GradientStops.Add(new GradientStop(Color.FromRgb(0xF9, 0xBB, 0x43), 1)); temp.Brush = brush; temp.Freeze(); _commonRadioButtonHoverHighlightPen = temp; } } } return _commonRadioButtonHoverHighlightPen; } } private Brush BackgroundBrush { get { if (!IsEnabled) { return CommonDisabledBackground; } if (RenderPressed) { return CommonPressedBackground; } else { return Background; } } } private static LinearGradientBrush CommonCheckBoxInnerFill { get { if (_commonCheckBoxInnerFill == null) { lock (_resourceAccess) { if (_commonCheckBoxInnerFill == null) { LinearGradientBrush temp = new LinearGradientBrush(); temp.StartPoint = new Point(0, 0); temp.EndPoint = new Point(1, 1); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0xCB, 0xCF, 0xD5), 0.3)); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0xF6, 0xF6, 0xF6), 1)); temp.Freeze(); _commonCheckBoxInnerFill = temp; } } } return _commonCheckBoxInnerFill; } } private static LinearGradientBrush CommonIndeterminateDisabledFill { get { if (_commonIndeterminateDisabledFill == null) { lock (_resourceAccess) { if (_commonIndeterminateDisabledFill == null) { LinearGradientBrush temp = new LinearGradientBrush(); temp.StartPoint = new Point(0, 0); temp.EndPoint = new Point(1, 1); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0x2F, 0xA8, 0xD5), 0)); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0x25, 0x59, 0x8C), 1)); temp.Freeze(); _commonIndeterminateDisabledFill = temp; } } } return _commonIndeterminateDisabledFill; } } private static SolidColorBrush CommonIndeterminateFill { get { if (_commonIndeterminateFill == null) { lock (_resourceAccess) { if (_commonIndeterminateFill == null) { SolidColorBrush temp = new SolidColorBrush(Color.FromRgb(0x73, 0xC2, 0x73)); temp.Freeze(); _commonIndeterminateFill = temp; } } } return _commonIndeterminateFill; } } private static LinearGradientBrush CommonIndeterminatePressedFill { get { if (_commonIndeterminatePressedFill == null) { lock (_resourceAccess) { if (_commonIndeterminatePressedFill == null) { LinearGradientBrush temp = new LinearGradientBrush(); temp.StartPoint = new Point(0, 0); temp.EndPoint = new Point(1, 1); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0x17, 0x74, 0x7A), 0)); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0x21, 0x8B, 0xC3), 1)); temp.Freeze(); _commonIndeterminatePressedFill = temp; } } } return _commonIndeterminatePressedFill; } } private Brush GlyphFill { get { if (!IsEnabled) { if (IsChecked != false) { return CommonDisabledGlyphFill; } else { return null; } } if (!IsRound) { if (IsChecked == true) { if (RenderPressed) { return CommonCheckMarkPressedFill; } else { return CommonCheckMarkFill; } } else if (IsChecked == null) { if (RenderPressed) { return CommonCheckMarkPressedFill; } else { return CommonIndeterminateFill; } } else { return null; } } else { if (IsChecked == true) { return CommonRadioButtonGlyphFill; } else { return null; } } } } private Pen BorderPen { get { if (!IsEnabled) { return CommonDisabledBorderPen; } return GetBorderPen(BorderBrush); } } private Pen HighlightPen { get { if (!RenderMouseOver || RenderPressed || !IsEnabled) { return null; } if (!IsRound) { return CommonCheckBoxHoverHighlightPen; } else { return CommonRadioButtonHoverHighlightPen; } } } // Common Resources private static Geometry _checkMarkGeometry; private static SolidColorBrush _commonCheckMarkFill; private static SolidColorBrush _commonCheckMarkPressedFill; private static LinearGradientBrush _commonRadioButtonGlyphFill; private static SolidColorBrush _commonIndeterminateFill; private static LinearGradientBrush _commonIndeterminatePressedFill; private static LinearGradientBrush _commonIndeterminateDisabledFill; private static Pen _commonBorderPen; private static LinearGradientBrush _commonCheckBoxInnerFill; private static SolidColorBrush _commonDisabledBorder; private static Pen _commonDisabledBorderPen; private static Pen _commonCheckBoxHoverHighlightPen; private static Pen _commonRadioButtonHoverHighlightPen; private static LinearGradientBrush _commonPressedBackground; private static object _resourceAccess = new object(); #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // File: BulletChrome.cs // // Description: // Implementation of CheckBox and RadioButtons in Luna and Royale. // // Copyright (C) 2006 by Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System.Windows.Shapes; using System.Windows.Controls; using System.Diagnostics; using System.Threading; using System.Windows; using System.Windows.Media; using MS.Internal; using System; namespace Microsoft.Windows.Themes { public sealed class BulletChrome : FrameworkElement { #region Constructors static BulletChrome() { IsEnabledProperty.OverrideMetadata(typeof(BulletChrome), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender)); } ////// Instantiates a new instance of a BulletChrome with no parent element. /// public BulletChrome() { } #endregion Constructors #region Dynamic Properties ////// DependencyProperty for public static readonly DependencyProperty BackgroundProperty = Control.BackgroundProperty.AddOwner( typeof(BulletChrome), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// The Background property defines the brush used to fill the background of the button. /// public Brush Background { get { return (Brush) GetValue(BackgroundProperty); } set { SetValue(BackgroundProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty BorderBrushProperty = System.Windows.Controls.Border.BorderBrushProperty.AddOwner( typeof(BulletChrome), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// The BorderBrush property defines the brush used to draw the outer border. /// public Brush BorderBrush { get { return (Brush) GetValue(BorderBrushProperty); } set { SetValue(BorderBrushProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty BorderThicknessProperty = System.Windows.Controls.Border.BorderThicknessProperty.AddOwner(typeof(BulletChrome)); ///property. /// /// The BorderThickness property defines the Thickness used to draw the outer border. /// public Thickness BorderThickness { get { return (Thickness)GetValue(BorderThicknessProperty); } set { SetValue(BorderThicknessProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty RenderMouseOverProperty = DependencyProperty.Register("RenderMouseOver", typeof(bool), typeof(BulletChrome), new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// When true the chrome renders with a mouse over look. /// public bool RenderMouseOver { get { return (bool)GetValue(RenderMouseOverProperty); } set { SetValue(RenderMouseOverProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty RenderPressedProperty = DependencyProperty.Register("RenderPressed", typeof(bool), typeof(BulletChrome), new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// When true the chrome renders with a pressed look. /// public bool RenderPressed { get { return (bool)GetValue(RenderPressedProperty); } set { SetValue(RenderPressedProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register("IsChecked", typeof(bool?), typeof(BulletChrome), new FrameworkPropertyMetadata( ((bool?)false), FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// When true, the left border will have round corners, otherwise they will be square. /// public bool? IsChecked { get { return (bool?)GetValue(IsCheckedProperty); } set { SetValue(IsCheckedProperty, value); } } ////// DependencyProperty for public static readonly DependencyProperty IsRoundProperty = DependencyProperty.Register("IsRound", typeof(bool), typeof(BulletChrome), new FrameworkPropertyMetadata( false, FrameworkPropertyMetadataOptions.AffectsRender)); ///property. /// /// When true, the left border will have round corners, otherwise they will be square. /// public bool IsRound { get { return (bool)GetValue(IsRoundProperty); } set { SetValue(IsRoundProperty, value); } } #endregion Dynamic Properties #region Protected Methods ////// Updates DesiredSize of the BulletChrome. Called by parent UIElement. This is the first pass of layout. /// /// Available size is an "upper limit" that the return value should not exceed. ///The BulletChrome's desired size. protected override Size MeasureOverride(Size availableSize) { Thickness thickness = BorderThickness; bool isRound = IsRound; double borderX = isRound ? 2.0 : thickness.Left + thickness.Right; double borderY = isRound ? 2.0 : thickness.Top + thickness.Bottom; Size desired; desired = new Size(Math.Min(11.0 + borderX, availableSize.Width), Math.Min(11.0 + borderY, availableSize.Height)); return desired; } ////// Render callback. /// protected override void OnRender(DrawingContext drawingContext) { Thickness thickness = BorderThickness; bool isUnitThickness = thickness.Left == 1.0 && thickness.Right == 1.0 && thickness.Top == 1.0 && thickness.Bottom == 1.0; Rect bounds = new Rect(0, 0, ActualWidth, ActualHeight); Rect innerBounds = bounds; // Apply BorderThickness to Checkbox only if (!IsRound) { innerBounds = new Rect(thickness.Left, thickness.Top, Math.Max(0, bounds.Width - thickness.Left - thickness.Right), Math.Max(0, bounds.Height - thickness.Top - thickness.Bottom)); } // Draw Background DrawBackground(drawingContext, ref innerBounds); // Draw innerborder and fill with inner fill DrawHighlight(drawingContext, ref innerBounds); DrawGlyph(drawingContext, ref innerBounds, isUnitThickness); // Draw outer border DrawBorder(drawingContext, ref bounds, thickness, isUnitThickness); } private void DrawBackground(DrawingContext dc, ref Rect bounds) { Brush fill = BackgroundBrush; if (fill != null && (bounds.Width > 2.0) && (bounds.Height > 2.0)) { if (!IsRound) { // Draw Background dc.DrawRectangle(fill, null, bounds); } else { double centerX = bounds.Width * 0.5; double centerY = bounds.Height * 0.5; // Draw Background dc.DrawEllipse(fill, null, new Point(centerX, centerY), centerX - 1, centerY - 1); } } } // Draw the inner border private void DrawHighlight(DrawingContext dc, ref Rect bounds) { Pen highlightPen = HighlightPen; if (highlightPen != null && (bounds.Width >= 4.0) && (bounds.Height >= 4.0)) { if (!IsRound) { dc.DrawRectangle(null, highlightPen, new Rect(bounds.Left + 1.0, bounds.Top + 1.0, bounds.Width - 2.0, bounds.Height - 2.0)); } else { double centerX = bounds.Width * 0.5; double centerY = bounds.Height * 0.5; dc.DrawEllipse(null, highlightPen, new Point(centerX, centerY), centerX - 2, centerY - 2); } } } // Draw the CheckMark or Dot private void DrawGlyph(DrawingContext dc, ref Rect bounds, bool isUnitThickness) { Brush glyphFill = GlyphFill; if (glyphFill != null && (bounds.Width > 4.0) && (bounds.Height > 4.0)) { if (!IsRound) { if (IsChecked == true) { // Translate Glyph if not 1px borders if (!isUnitThickness) { dc.PushTransform(new TranslateTransform(bounds.Left - 1.0, bounds.Top - 1.0)); } // Need to reverse Checkbox in RTL so it draws to screen the same as LTR if (FlowDirection == FlowDirection.RightToLeft) { dc.PushTransform(new ScaleTransform(-1.0, 1.0, 6.5, 0)); } dc.DrawGeometry(glyphFill, null, CheckMarkGeometry); if (FlowDirection == FlowDirection.RightToLeft) { dc.Pop(); } if (!isUnitThickness) { dc.Pop(); } } else if (IsChecked == null) { dc.DrawRectangle(glyphFill, null, new Rect(bounds.Left + 2, bounds.Top + 2, bounds.Width - 4.0, bounds.Height - 4.0)); } } else { if ((bounds.Width > 8.0) && (bounds.Height > 8.0)) { double centerX = bounds.Width * 0.5; double centerY = bounds.Height * 0.5; dc.DrawEllipse(glyphFill, null, new Point(centerX, centerY), centerX - 4, centerY - 4); } } } } // Draw the main border private void DrawBorder(DrawingContext dc, ref Rect bounds, Thickness thickness, bool isUnitThickness) { if ((bounds.Width >= 5.0) && (bounds.Height >= 5.0)) { if (!IsRound) { if (isUnitThickness) { Pen borderPen = BorderPen; if (borderPen != null) { Rect rect = new Rect(bounds.Left + 0.5, bounds.Top + 0.5, bounds.Width - 1.0, bounds.Height - 1.0); dc.DrawRectangle(null, borderPen, rect); } } else { Brush borderBrush = Border; if (borderBrush != null) { dc.DrawGeometry(borderBrush, null, GenerateBorderGeometry(bounds, thickness)); } } } else // IsRound == true { Pen borderPen = BorderPen; if (borderPen != null) { double centerX = bounds.Width * 0.5; double centerY = bounds.Height * 0.5; dc.DrawEllipse(null, borderPen, new Point(centerX, centerY), centerX - 0.5, centerY - 0.5); } } } } private static Pen GetBorderPen(Brush border) { Pen pen = null; if (border != null) { if (_commonBorderPen == null) // Common case, if non-null, avoid the lock { lock (_resourceAccess) // If non-null, lock to create the pen for thread safety { if (_commonBorderPen == null) // Check again in case _pen was created within the last line { // Assume that the first render of Button uses the most common brush for the app. // This breaks down if (a) the first Button is disabled, (b) the first Button is // customized, or (c) BulletChrome becomes more broadly used than just on Button. // // If these cons sufficiently weaken the effectiveness of this cache, then we need // to build a larger brush-to-pen mapping cache. // If the brush is not already frozen, we need to create our own // copy. Otherwise we will inadvertently freeze the user's // BorderBrush when we freeze the pen below. if (!border.IsFrozen && border.CanFreeze) { border = border.Clone(); border.Freeze(); } Pen commonPen = new Pen(border, 1); if (commonPen.CanFreeze) { // Only save frozen pens, some brushes such as VisualBrush // can not be frozen commonPen.Freeze(); _commonBorderPen = commonPen; } } } } if (_commonBorderPen != null && border == _commonBorderPen.Brush) { pen = _commonBorderPen; } else { if (!border.IsFrozen && border.CanFreeze) { border = border.Clone(); border.Freeze(); } pen = new Pen(border, 1); if (pen.CanFreeze) { pen.Freeze(); } } } return pen; } #endregion #region Private Properties // // This property // 1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject // 2. This is a performance optimization // internal override int EffectiveValuesInitialSize { get { return 9; } } /// Helper to deflate rectangle by thickness private static Rect HelperDeflateRect(Rect rt, Thickness thick) { return new Rect(rt.Left + thick.Left, rt.Top + thick.Top, Math.Max(0.0, rt.Width - thick.Left - thick.Right), Math.Max(0.0, rt.Height - thick.Top - thick.Bottom)); } // Creates a rectangle figure private static PathFigure GenerateRectFigure(Rect rect) { PathFigure figure = new PathFigure(); figure.StartPoint = rect.TopLeft; figure.Segments.Add(new LineSegment(rect.TopRight, true)); figure.Segments.Add(new LineSegment(rect.BottomRight, true)); figure.Segments.Add(new LineSegment(rect.BottomLeft, true)); figure.IsClosed = true; figure.Freeze(); return figure; } // Creates a border geometry used to render complex border brushes private static Geometry GenerateBorderGeometry(Rect rect, Thickness borderThickness) { PathGeometry geometry = new PathGeometry(); // Add outer rectangle figure geometry.Figures.Add(GenerateRectFigure(rect)); // Subtract inner rectangle figure geometry.Figures.Add(GenerateRectFigure(HelperDeflateRect(rect, borderThickness))); geometry.Freeze(); return geometry; } private static Geometry CheckMarkGeometry { get { if (_checkMarkGeometry == null) { lock (_resourceAccess) { if (_checkMarkGeometry == null) { StreamGeometry geometry = new StreamGeometry(); StreamGeometryContext sgc = geometry.Open(); sgc.BeginFigure(new Point(3, 5.0), true, true); sgc.LineTo(new Point(3, 7.8), false, false); sgc.LineTo(new Point(5.5, 10.4), false, false); sgc.LineTo(new Point(10.1, 5.8), false, false); sgc.LineTo(new Point(10.1, 3), false, false); sgc.LineTo(new Point(5.5, 7.6), false, false); sgc.Close(); geometry.Freeze(); _checkMarkGeometry = geometry; } } } return _checkMarkGeometry; } } private static SolidColorBrush CommonDisabledGlyphFill { get { return CommonDisabledBorder; } } private static SolidColorBrush CommonCheckMarkFill { get { if (_commonCheckMarkFill == null) { lock (_resourceAccess) { if (_commonCheckMarkFill == null) { SolidColorBrush temp = new SolidColorBrush(Color.FromRgb(0x21, 0xA1, 0x21)); temp.Freeze(); _commonCheckMarkFill = temp; } } } return _commonCheckMarkFill; } } private static SolidColorBrush CommonCheckMarkPressedFill { get { if (_commonCheckMarkPressedFill == null) { lock (_resourceAccess) { if (_commonCheckMarkPressedFill == null) { SolidColorBrush temp = new SolidColorBrush(Color.FromRgb(0x1A, 0x7E, 0x18)); temp.Freeze(); _commonCheckMarkPressedFill = temp; } } } return _commonCheckMarkPressedFill; } } private static LinearGradientBrush CommonRadioButtonGlyphFill { get { if (_commonRadioButtonGlyphFill == null) { lock (_resourceAccess) { if (_commonRadioButtonGlyphFill == null) { LinearGradientBrush temp = new LinearGradientBrush(); temp.StartPoint = new Point(); temp.EndPoint = new Point(1, 1); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0x60, 0xCF, 0x5D), 0)); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0xAC, 0xEF, 0xAA), 0.302469134)); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0x13, 0x92, 0x10), 1)); temp.Freeze(); _commonRadioButtonGlyphFill = temp; } } } return _commonRadioButtonGlyphFill; } } private static LinearGradientBrush CommonPressedBackground { get { if (_commonPressedBackground == null) { lock (_resourceAccess) { if (_commonPressedBackground == null) { LinearGradientBrush temp = new LinearGradientBrush(); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0xB2, 0xB2, 0xA9), 0)); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0xEB, 0xEA, 0xDA), 1)); temp.Freeze(); _commonPressedBackground = temp; } } } return _commonPressedBackground; } } private static SolidColorBrush CommonDisabledBackground { get { return Brushes.White; } } private static SolidColorBrush CommonDisabledBorder { get { if (_commonDisabledBorder == null) { lock (_resourceAccess) { if (_commonDisabledBorder == null) { SolidColorBrush temp = new SolidColorBrush(Color.FromRgb(0xCA, 0xC8, 0xBB)); temp.Freeze(); _commonDisabledBorder = temp; } } } return _commonDisabledBorder; } } private Brush Border { get { if (!IsEnabled) { return CommonDisabledBorder; } return BorderBrush; } } private static Pen CommonDisabledBorderPen { get { if (_commonDisabledBorderPen == null) { lock (_resourceAccess) { if (_commonDisabledBorderPen == null) { Pen temp = new Pen(); temp.Thickness = 1; temp.Brush = CommonDisabledBorder; temp.Freeze(); _commonDisabledBorderPen = temp; } } } return _commonDisabledBorderPen; } } private static Pen CommonCheckBoxHoverHighlightPen { get { if (_commonCheckBoxHoverHighlightPen == null) { lock (_resourceAccess) { if (_commonCheckBoxHoverHighlightPen == null) { Pen temp = new Pen(); temp.Thickness = 2; LinearGradientBrush brush = new LinearGradientBrush(); brush.StartPoint = new Point(0, 0); brush.EndPoint = new Point(1, 1); brush.GradientStops.Add(new GradientStop(Color.FromRgb(0xFF, 0xF0, 0xCF), 0)); brush.GradientStops.Add(new GradientStop(Color.FromRgb(0xF8, 0xB3, 0x30), 1)); temp.Brush = brush; temp.Freeze(); _commonCheckBoxHoverHighlightPen = temp; } } } return _commonCheckBoxHoverHighlightPen; } } private static Pen CommonRadioButtonHoverHighlightPen { get { if (_commonRadioButtonHoverHighlightPen == null) { lock (_resourceAccess) { if (_commonRadioButtonHoverHighlightPen == null) { Pen temp = new Pen(); temp.Thickness = 2; LinearGradientBrush brush = new LinearGradientBrush(); brush.StartPoint = new Point(0, 0); brush.EndPoint = new Point(1, 1); brush.GradientStops.Add(new GradientStop(Color.FromRgb(0xFE, 0xDF, 0x9C), 0)); brush.GradientStops.Add(new GradientStop(Color.FromRgb(0xF9, 0xBB, 0x43), 1)); temp.Brush = brush; temp.Freeze(); _commonRadioButtonHoverHighlightPen = temp; } } } return _commonRadioButtonHoverHighlightPen; } } private Brush BackgroundBrush { get { if (!IsEnabled) { return CommonDisabledBackground; } if (RenderPressed) { return CommonPressedBackground; } else { return Background; } } } private static LinearGradientBrush CommonCheckBoxInnerFill { get { if (_commonCheckBoxInnerFill == null) { lock (_resourceAccess) { if (_commonCheckBoxInnerFill == null) { LinearGradientBrush temp = new LinearGradientBrush(); temp.StartPoint = new Point(0, 0); temp.EndPoint = new Point(1, 1); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0xCB, 0xCF, 0xD5), 0.3)); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0xF6, 0xF6, 0xF6), 1)); temp.Freeze(); _commonCheckBoxInnerFill = temp; } } } return _commonCheckBoxInnerFill; } } private static LinearGradientBrush CommonIndeterminateDisabledFill { get { if (_commonIndeterminateDisabledFill == null) { lock (_resourceAccess) { if (_commonIndeterminateDisabledFill == null) { LinearGradientBrush temp = new LinearGradientBrush(); temp.StartPoint = new Point(0, 0); temp.EndPoint = new Point(1, 1); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0x2F, 0xA8, 0xD5), 0)); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0x25, 0x59, 0x8C), 1)); temp.Freeze(); _commonIndeterminateDisabledFill = temp; } } } return _commonIndeterminateDisabledFill; } } private static SolidColorBrush CommonIndeterminateFill { get { if (_commonIndeterminateFill == null) { lock (_resourceAccess) { if (_commonIndeterminateFill == null) { SolidColorBrush temp = new SolidColorBrush(Color.FromRgb(0x73, 0xC2, 0x73)); temp.Freeze(); _commonIndeterminateFill = temp; } } } return _commonIndeterminateFill; } } private static LinearGradientBrush CommonIndeterminatePressedFill { get { if (_commonIndeterminatePressedFill == null) { lock (_resourceAccess) { if (_commonIndeterminatePressedFill == null) { LinearGradientBrush temp = new LinearGradientBrush(); temp.StartPoint = new Point(0, 0); temp.EndPoint = new Point(1, 1); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0x17, 0x74, 0x7A), 0)); temp.GradientStops.Add(new GradientStop(Color.FromRgb(0x21, 0x8B, 0xC3), 1)); temp.Freeze(); _commonIndeterminatePressedFill = temp; } } } return _commonIndeterminatePressedFill; } } private Brush GlyphFill { get { if (!IsEnabled) { if (IsChecked != false) { return CommonDisabledGlyphFill; } else { return null; } } if (!IsRound) { if (IsChecked == true) { if (RenderPressed) { return CommonCheckMarkPressedFill; } else { return CommonCheckMarkFill; } } else if (IsChecked == null) { if (RenderPressed) { return CommonCheckMarkPressedFill; } else { return CommonIndeterminateFill; } } else { return null; } } else { if (IsChecked == true) { return CommonRadioButtonGlyphFill; } else { return null; } } } } private Pen BorderPen { get { if (!IsEnabled) { return CommonDisabledBorderPen; } return GetBorderPen(BorderBrush); } } private Pen HighlightPen { get { if (!RenderMouseOver || RenderPressed || !IsEnabled) { return null; } if (!IsRound) { return CommonCheckBoxHoverHighlightPen; } else { return CommonRadioButtonHoverHighlightPen; } } } // Common Resources private static Geometry _checkMarkGeometry; private static SolidColorBrush _commonCheckMarkFill; private static SolidColorBrush _commonCheckMarkPressedFill; private static LinearGradientBrush _commonRadioButtonGlyphFill; private static SolidColorBrush _commonIndeterminateFill; private static LinearGradientBrush _commonIndeterminatePressedFill; private static LinearGradientBrush _commonIndeterminateDisabledFill; private static Pen _commonBorderPen; private static LinearGradientBrush _commonCheckBoxInnerFill; private static SolidColorBrush _commonDisabledBorder; private static Pen _commonDisabledBorderPen; private static Pen _commonCheckBoxHoverHighlightPen; private static Pen _commonRadioButtonHoverHighlightPen; private static LinearGradientBrush _commonPressedBackground; private static object _resourceAccess = new object(); #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BufferBuilder.cs
- XmlExpressionDumper.cs
- KerberosSecurityTokenAuthenticator.cs
- LayoutEditorPart.cs
- XmlEventCache.cs
- SchemaNames.cs
- MenuRendererStandards.cs
- TextRange.cs
- HttpProfileBase.cs
- CachingHintValidation.cs
- StringDictionaryEditor.cs
- CoTaskMemUnicodeSafeHandle.cs
- WebPartTracker.cs
- PreservationFileReader.cs
- ReferenceEqualityComparer.cs
- RegexReplacement.cs
- FieldDescriptor.cs
- NullableConverter.cs
- CountdownEvent.cs
- FilterQuery.cs
- ObjectItemConventionAssemblyLoader.cs
- Int16Animation.cs
- RepeaterCommandEventArgs.cs
- ItemAutomationPeer.cs
- ImmComposition.cs
- XmlSerializerAssemblyAttribute.cs
- CollectionViewGroup.cs
- GZipDecoder.cs
- Thread.cs
- TemplateBindingExpressionConverter.cs
- MenuRenderer.cs
- DynamicPropertyReader.cs
- SelectorAutomationPeer.cs
- PasswordDeriveBytes.cs
- ChangesetResponse.cs
- TableRowGroup.cs
- OlePropertyStructs.cs
- NotSupportedException.cs
- NamedPermissionSet.cs
- ListViewItem.cs
- OneWayChannelFactory.cs
- SqlColumnizer.cs
- GeneratedView.cs
- ConnectionManagementElementCollection.cs
- XmlFormatExtensionPointAttribute.cs
- Reference.cs
- SystemColorTracker.cs
- HtmlMeta.cs
- WaitForChangedResult.cs
- GeneralTransform3DGroup.cs
- TextTreeTextBlock.cs
- StructuralObject.cs
- XmlConvert.cs
- LongCountAggregationOperator.cs
- COMException.cs
- WebServiceEnumData.cs
- MSG.cs
- PassportAuthenticationModule.cs
- DrawingVisual.cs
- DataFormat.cs
- ExpressionLexer.cs
- ValidationService.cs
- FileDialog_Vista_Interop.cs
- GuidConverter.cs
- TypeElement.cs
- RemotingException.cs
- Certificate.cs
- BaseTreeIterator.cs
- ZipIOBlockManager.cs
- HttpResponseInternalWrapper.cs
- ConstantProjectedSlot.cs
- Pool.cs
- odbcmetadatacollectionnames.cs
- FileNameEditor.cs
- EventLogEntry.cs
- ColumnMapCopier.cs
- ConfigurationErrorsException.cs
- PipelineModuleStepContainer.cs
- MyContact.cs
- ListCollectionView.cs
- VirtualDirectoryMapping.cs
- SoapAttributes.cs
- AnnotationResourceChangedEventArgs.cs
- AdapterSwitches.cs
- ToolBar.cs
- ConstantSlot.cs
- ImageField.cs
- HtmlLiteralTextAdapter.cs
- PeerNameRegistration.cs
- SqlClientMetaDataCollectionNames.cs
- ScrollBarRenderer.cs
- DiagnosticsConfiguration.cs
- ElementProxy.cs
- PointConverter.cs
- HashFinalRequest.cs
- SchemaCollectionCompiler.cs
- TrackingQuery.cs
- SiteMapPath.cs
- PipelineDeploymentState.cs
- Stream.cs