Init
This commit is contained in:
@@ -0,0 +1,260 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using Xceed.Wpf.Toolkit.Core;
|
||||
using Xceed.Wpf.Toolkit.Core.Utilities;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit
|
||||
{
|
||||
public class RichTextBoxFormatBarManager : DependencyObject
|
||||
{
|
||||
#region Members
|
||||
|
||||
private global::System.Windows.Controls.RichTextBox _richTextBox;
|
||||
private UIElementAdorner<Control> _adorner;
|
||||
private IRichTextBoxFormatBar _toolbar;
|
||||
private Window _parentWindow;
|
||||
|
||||
private const double _hideAdornerDistance = 150d;
|
||||
|
||||
#endregion //Members
|
||||
|
||||
#region Properties
|
||||
|
||||
#region FormatBar
|
||||
|
||||
public static readonly DependencyProperty FormatBarProperty = DependencyProperty.RegisterAttached( "FormatBar", typeof( IRichTextBoxFormatBar ), typeof( RichTextBox ), new PropertyMetadata( null, OnFormatBarPropertyChanged ) );
|
||||
public static void SetFormatBar( UIElement element, IRichTextBoxFormatBar value )
|
||||
{
|
||||
element.SetValue( FormatBarProperty, value );
|
||||
}
|
||||
public static IRichTextBoxFormatBar GetFormatBar( UIElement element )
|
||||
{
|
||||
return ( IRichTextBoxFormatBar )element.GetValue( FormatBarProperty );
|
||||
}
|
||||
|
||||
private static void OnFormatBarPropertyChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
|
||||
{
|
||||
global::System.Windows.Controls.RichTextBox rtb = d as global::System.Windows.Controls.RichTextBox;
|
||||
if( rtb == null )
|
||||
throw new Exception( "A FormatBar can only be applied to a RichTextBox." );
|
||||
|
||||
RichTextBoxFormatBarManager manager = new RichTextBoxFormatBarManager();
|
||||
manager.AttachFormatBarToRichtextBox( rtb, e.NewValue as IRichTextBoxFormatBar );
|
||||
}
|
||||
|
||||
#endregion //FormatBar
|
||||
|
||||
public bool IsAdornerVisible
|
||||
{
|
||||
get
|
||||
{
|
||||
return _adorner.Visibility == Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //Properties
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
void RichTextBox_MouseButtonUp( object sender, MouseButtonEventArgs e )
|
||||
{
|
||||
if( e.ChangedButton == MouseButton.Left && e.LeftButton == MouseButtonState.Released )
|
||||
{
|
||||
if( !_richTextBox.IsReadOnly )
|
||||
{
|
||||
TextRange selectedText = new TextRange( _richTextBox.Selection.Start, _richTextBox.Selection.End );
|
||||
#if !VS2008
|
||||
if( selectedText.Text.Length > 0 && !String.IsNullOrWhiteSpace( selectedText.Text ) )
|
||||
ShowAdorner();
|
||||
#else
|
||||
if( selectedText.Text.Length > 0 && !String.IsNullOrEmpty( selectedText.Text ) )
|
||||
ShowAdorner();
|
||||
#endif
|
||||
else
|
||||
HideAdorner();
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
HideAdorner();
|
||||
}
|
||||
|
||||
private void OnPreviewMouseMoveParentWindow( object sender, MouseEventArgs e )
|
||||
{
|
||||
Point p = e.GetPosition( _adorner );
|
||||
double maxDist = 0d;
|
||||
bool preventDisplayFadeOut = ( ( _adorner.Child != null ) && ( _adorner.Child is IRichTextBoxFormatBar ) ) ?
|
||||
( ( IRichTextBoxFormatBar )_adorner.Child ).PreventDisplayFadeOut :
|
||||
false;
|
||||
|
||||
//Mouse is inside FormatBar: Nothing to do.
|
||||
if( preventDisplayFadeOut ||
|
||||
( p.X >= 0 ) && ( p.X <= _adorner.ActualWidth ) && ( p.Y >= 0 ) && ( p.Y <= _adorner.ActualHeight ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
//Mouse is too much outside FormatBar: Close it.
|
||||
else if( ( p.X < -_hideAdornerDistance ) || ( p.X > _adorner.ActualWidth + _hideAdornerDistance ) || ( p.Y < -_hideAdornerDistance ) || ( p.Y > _adorner.ActualHeight + _hideAdornerDistance ) )
|
||||
{
|
||||
HideAdorner();
|
||||
}
|
||||
//Mouse is just outside FormatBar: Vary its opacity.
|
||||
else
|
||||
{
|
||||
if( p.X < 0 )
|
||||
maxDist = -p.X;
|
||||
else if( p.X > _adorner.ActualWidth )
|
||||
maxDist = p.X - _adorner.ActualWidth;
|
||||
|
||||
if( p.Y < 0 )
|
||||
maxDist = Math.Max( maxDist, -p.Y );
|
||||
else if( p.Y > _adorner.ActualHeight )
|
||||
maxDist = Math.Max( maxDist, p.Y - _adorner.ActualHeight );
|
||||
|
||||
_adorner.Opacity = 1d - ( Math.Min( maxDist, 100d ) / 100d );
|
||||
}
|
||||
}
|
||||
|
||||
void RichTextBox_TextChanged( object sender, TextChangedEventArgs e )
|
||||
{
|
||||
//This fixes the bug when applying text transformations the text would lose it's highlight. That was because the RichTextBox was losing focus,
|
||||
//so we just give it focus again and it seems to do the trick of re-highlighting it.
|
||||
if( !_richTextBox.IsFocused && !_richTextBox.Selection.IsEmpty )
|
||||
_richTextBox.Focus();
|
||||
}
|
||||
|
||||
#endregion //Event Handlers
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a FormatBar to a RichtextBox
|
||||
/// </summary>
|
||||
/// <param name="richTextBox">The RichtextBox to attach to.</param>
|
||||
/// <param name="formatBar">The Formatbar to attach.</param>
|
||||
private void AttachFormatBarToRichtextBox( global::System.Windows.Controls.RichTextBox richTextBox, IRichTextBoxFormatBar formatBar )
|
||||
{
|
||||
_richTextBox = richTextBox;
|
||||
//we cannot use the PreviewMouseLeftButtonUp event because of selection bugs.
|
||||
//we cannot use the MouseLeftButtonUp event because it is handled by the RichTextBox and does not bubble up to here, so we must
|
||||
//add a hander to the MouseUpEvent using the Addhandler syntax, and specify to listen for handled events too.
|
||||
_richTextBox.AddHandler( Mouse.MouseUpEvent, new MouseButtonEventHandler( RichTextBox_MouseButtonUp ), true );
|
||||
_richTextBox.TextChanged += RichTextBox_TextChanged;
|
||||
|
||||
_adorner = new UIElementAdorner<Control>( _richTextBox );
|
||||
|
||||
formatBar.Target = _richTextBox;
|
||||
_toolbar = formatBar;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the FormatBar
|
||||
/// </summary>
|
||||
void ShowAdorner()
|
||||
{
|
||||
if( _adorner.Visibility == Visibility.Visible )
|
||||
return;
|
||||
|
||||
VerifyAdornerLayer();
|
||||
|
||||
Control adorningEditor = _toolbar as Control;
|
||||
|
||||
if( _adorner.Child == null )
|
||||
_adorner.Child = adorningEditor;
|
||||
|
||||
adorningEditor.ApplyTemplate();
|
||||
_toolbar.Update();
|
||||
|
||||
_adorner.Visibility = Visibility.Visible;
|
||||
|
||||
PositionFormatBar( adorningEditor );
|
||||
|
||||
_parentWindow = TreeHelper.FindParent<Window>( _adorner );
|
||||
if( _parentWindow != null )
|
||||
{
|
||||
Mouse.AddMouseMoveHandler( _parentWindow, OnPreviewMouseMoveParentWindow );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Positions the FormatBar so that is does not go outside the bounds of the RichTextBox or covers the selected text
|
||||
/// </summary>
|
||||
/// <param name="adorningEditor"></param>
|
||||
private void PositionFormatBar( Control adorningEditor )
|
||||
{
|
||||
Point mousePosition = Mouse.GetPosition( _richTextBox );
|
||||
|
||||
double left = mousePosition.X;
|
||||
double top = ( mousePosition.Y - 15 ) - adorningEditor.ActualHeight;
|
||||
|
||||
//top
|
||||
if( top < 0 )
|
||||
{
|
||||
top = mousePosition.Y + 10;
|
||||
}
|
||||
|
||||
//right boundary
|
||||
if( left + adorningEditor.ActualWidth > _richTextBox.ActualWidth - 20 )
|
||||
{
|
||||
left = left - ( adorningEditor.ActualWidth - ( _richTextBox.ActualWidth - left ) );
|
||||
}
|
||||
|
||||
_adorner.SetOffsets( left, top );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the IRichTextFormatBar is in the adorner layer.
|
||||
/// </summary>
|
||||
/// <returns>True if the IRichTextFormatBar is in the adorner layer, else false.</returns>
|
||||
bool VerifyAdornerLayer()
|
||||
{
|
||||
if( _adorner.Parent != null )
|
||||
return true;
|
||||
|
||||
AdornerLayer layer = AdornerLayer.GetAdornerLayer( _richTextBox );
|
||||
if( layer == null )
|
||||
return false;
|
||||
|
||||
layer.Add( _adorner );
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hides the IRichTextFormatBar that is in the adornor layer.
|
||||
/// </summary>
|
||||
void HideAdorner()
|
||||
{
|
||||
if( IsAdornerVisible )
|
||||
{
|
||||
_adorner.Visibility = Visibility.Collapsed;
|
||||
//_adorner.Child = null;
|
||||
if( _parentWindow != null )
|
||||
{
|
||||
Mouse.RemoveMouseMoveHandler( _parentWindow, OnPreviewMouseMoveParentWindow );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //Methods
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user