Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3625 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
220 changed files with 13 additions and 23687 deletions
@ -1,20 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System.Reflection; |
|
||||||
|
|
||||||
// Information about this assembly is defined by the following
|
|
||||||
// attributes.
|
|
||||||
//
|
|
||||||
// change them to the information which is associated with the assembly
|
|
||||||
// you compile.
|
|
||||||
|
|
||||||
[assembly: AssemblyTitle("XamlBinding")] |
|
||||||
[assembly: AssemblyDescription("Provides XAML integration in code-completion")] |
|
||||||
[assembly: AssemblyConfiguration("")] |
|
||||||
[assembly: AssemblyTrademark("")] |
|
||||||
[assembly: AssemblyCulture("")] |
|
||||||
@ -1,42 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <author name="Daniel Grunwald"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using ICSharpCode.SharpDevelop.Dom; |
|
||||||
|
|
||||||
namespace XamlBinding |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Description of XamlClassReturnType.
|
|
||||||
/// </summary>
|
|
||||||
public class XamlClassReturnType : ProxyReturnType |
|
||||||
{ |
|
||||||
XamlCompilationUnit compilationUnit; |
|
||||||
string xmlNamespace; |
|
||||||
string className; |
|
||||||
|
|
||||||
public XamlClassReturnType(XamlCompilationUnit compilationUnit, string xmlNamespace, string className) |
|
||||||
{ |
|
||||||
if (compilationUnit == null) |
|
||||||
throw new ArgumentNullException("compilationUnit"); |
|
||||||
|
|
||||||
this.compilationUnit = compilationUnit; |
|
||||||
this.xmlNamespace = xmlNamespace; |
|
||||||
this.className = className ?? ""; |
|
||||||
} |
|
||||||
|
|
||||||
public override IReturnType BaseType { |
|
||||||
get { |
|
||||||
return compilationUnit.FindType(xmlNamespace, className); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override string Name { |
|
||||||
get { return className; } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,99 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <author name="Daniel Grunwald"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using ICSharpCode.SharpDevelop.Gui; |
|
||||||
using System; |
|
||||||
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; |
|
||||||
using ICSharpCode.SharpDevelop.Dom; |
|
||||||
using ICSharpCode.TextEditor.Gui.CompletionWindow; |
|
||||||
using ICSharpCode.XmlEditor; |
|
||||||
|
|
||||||
namespace XamlBinding |
|
||||||
{ |
|
||||||
public class XamlCodeCompletionBinding : ICodeCompletionBinding |
|
||||||
{ |
|
||||||
public bool HandleKeyPress(SharpDevelopTextAreaControl editor, char ch) |
|
||||||
{ |
|
||||||
if (ch == '<') { |
|
||||||
editor.ShowCompletionWindow(new XamlCompletionDataProvider(XamlExpressionContext.Empty), ch); |
|
||||||
return true; |
|
||||||
} else if (char.IsLetter(ch)) { |
|
||||||
int offset = editor.ActiveTextAreaControl.TextArea.Caret.Offset; |
|
||||||
if (offset > 0) { |
|
||||||
char c = editor.Document.GetCharAt(offset - 1); |
|
||||||
if (c == ' ' || c == '\t') { |
|
||||||
XmlElementPath path = XmlParser.GetActiveElementStartPathAtIndex(editor.Text, offset); |
|
||||||
if (path != null && path.Elements.Count > 0) { |
|
||||||
editor.ShowCompletionWindow( |
|
||||||
new XamlCompletionDataProvider( |
|
||||||
new XamlExpressionContext(path, "", false) |
|
||||||
) { IsAttributeCompletion = true } |
|
||||||
, '\0'); |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
public bool CtrlSpace(SharpDevelopTextAreaControl editor) |
|
||||||
{ |
|
||||||
XamlCompletionDataProvider provider = new XamlCompletionDataProvider(); |
|
||||||
provider.AllowCompleteExistingExpression = true; |
|
||||||
editor.ShowCompletionWindow(provider, '\0'); |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class XamlCompletionDataProvider : CtrlSpaceCompletionDataProvider |
|
||||||
{ |
|
||||||
public XamlCompletionDataProvider() |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public XamlCompletionDataProvider(ExpressionContext overrideContext) |
|
||||||
: base(overrideContext) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public override CompletionDataProviderKeyResult ProcessKey(char key) |
|
||||||
{ |
|
||||||
if (key == ':' || key == '.') { |
|
||||||
return CompletionDataProviderKeyResult.NormalKey; |
|
||||||
} else { |
|
||||||
return base.ProcessKey(key); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsAttributeCompletion; |
|
||||||
|
|
||||||
public override bool InsertAction(ICompletionData data, ICSharpCode.TextEditor.TextArea textArea, int insertionOffset, char key) |
|
||||||
{ |
|
||||||
CodeCompletionData ccData = data as CodeCompletionData; |
|
||||||
if (IsAttributeCompletion && ccData != null) { |
|
||||||
textArea.Caret.Position = textArea.Document.OffsetToPosition(insertionOffset); |
|
||||||
textArea.InsertString(ccData.Text + "=\"\""); |
|
||||||
textArea.Caret.Column -= 1; |
|
||||||
|
|
||||||
SharpDevelopTextAreaControl editor = textArea.MotherTextEditorControl as SharpDevelopTextAreaControl; |
|
||||||
if (editor != null) { |
|
||||||
WorkbenchSingleton.SafeThreadAsyncCall( |
|
||||||
delegate { |
|
||||||
XamlCompletionDataProvider provider = new XamlCompletionDataProvider(); |
|
||||||
provider.AllowCompleteExistingExpression = true; |
|
||||||
editor.ShowCompletionWindow(provider, '\0'); |
|
||||||
} |
|
||||||
); |
|
||||||
} |
|
||||||
return false; |
|
||||||
} else { |
|
||||||
return base.InsertAction(data, textArea, insertionOffset, key); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,126 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <author name="Daniel Grunwald"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using ICSharpCode.SharpDevelop.Dom; |
|
||||||
using System.Collections; |
|
||||||
using System.Collections.Generic; |
|
||||||
|
|
||||||
namespace XamlBinding |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Description of XamlCompilationUnit.
|
|
||||||
/// </summary>
|
|
||||||
public class XamlCompilationUnit : DefaultCompilationUnit |
|
||||||
{ |
|
||||||
public XamlCompilationUnit(IProjectContent projectContent) : base(projectContent) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public IReturnType CreateType(string xmlNamespace, string className) |
|
||||||
{ |
|
||||||
if (xmlNamespace.StartsWith("clr-namespace:")) { |
|
||||||
return CreateClrNamespaceType(this.ProjectContent, xmlNamespace, className); |
|
||||||
} else { |
|
||||||
return new XamlClassReturnType(this, xmlNamespace, className); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static IReturnType CreateClrNamespaceType(IProjectContent pc, string xmlNamespace, string className) |
|
||||||
{ |
|
||||||
string namespaceName = GetNamespaceNameFromClrNamespace(xmlNamespace); |
|
||||||
return new GetClassReturnType(pc, namespaceName + "." + className, 0); |
|
||||||
} |
|
||||||
|
|
||||||
static string GetNamespaceNameFromClrNamespace(string xmlNamespace) |
|
||||||
{ |
|
||||||
string namespaceName = xmlNamespace.Substring("clr-namespace:".Length); |
|
||||||
int pos = namespaceName.IndexOf(';'); |
|
||||||
if (pos >= 0) { |
|
||||||
// we expect that the target type is also a reference of the project, so we
|
|
||||||
// can ignore the assembly part after the ;
|
|
||||||
namespaceName = namespaceName.Substring(0, pos); |
|
||||||
} |
|
||||||
return namespaceName; |
|
||||||
} |
|
||||||
|
|
||||||
public IReturnType FindType(string xmlNamespace, string className) |
|
||||||
{ |
|
||||||
return FindType(this.ProjectContent, xmlNamespace, className); |
|
||||||
} |
|
||||||
|
|
||||||
public static IReturnType FindType(IProjectContent pc, string xmlNamespace, string className) |
|
||||||
{ |
|
||||||
if (pc == null) |
|
||||||
throw new ArgumentNullException("pc"); |
|
||||||
if (xmlNamespace == null || className == null) |
|
||||||
return null; |
|
||||||
if (xmlNamespace.StartsWith("clr-namespace:")) { |
|
||||||
return CreateClrNamespaceType(pc, xmlNamespace, className); |
|
||||||
} else { |
|
||||||
IReturnType type = FindTypeInAssembly(pc, xmlNamespace, className); |
|
||||||
if (type != null) |
|
||||||
return type; |
|
||||||
foreach (IProjectContent p in pc.ReferencedContents) { |
|
||||||
type = FindTypeInAssembly(p, xmlNamespace, className); |
|
||||||
if (type != null) |
|
||||||
return type; |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static IReturnType FindTypeInAssembly(IProjectContent projectContent, string xmlNamespace, string className) |
|
||||||
{ |
|
||||||
foreach (IAttribute att in projectContent.GetAssemblyAttributes()) { |
|
||||||
if (att.PositionalArguments.Count == 2 |
|
||||||
&& att.AttributeType.FullyQualifiedName == "System.Windows.Markup.XmlnsDefinitionAttribute") |
|
||||||
{ |
|
||||||
string namespaceName = att.PositionalArguments[1] as string; |
|
||||||
if (xmlNamespace.Equals(att.PositionalArguments[0]) && namespaceName != null) { |
|
||||||
IClass c = projectContent.GetClass(namespaceName + "." + className, 0, LanguageProperties.CSharp, GetClassOptions.None); |
|
||||||
if (c != null) |
|
||||||
return c.DefaultReturnType; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
public static ArrayList GetNamespaceMembers(IProjectContent pc, string xmlNamespace) |
|
||||||
{ |
|
||||||
if (pc == null) |
|
||||||
throw new ArgumentNullException("pc"); |
|
||||||
if (xmlNamespace == null) |
|
||||||
return null; |
|
||||||
if (xmlNamespace.StartsWith("clr-namespace:")) { |
|
||||||
return pc.GetNamespaceContents(GetNamespaceNameFromClrNamespace(xmlNamespace)); |
|
||||||
} else { |
|
||||||
ArrayList list = new ArrayList(); |
|
||||||
AddNamespaceMembersInAssembly(pc, xmlNamespace, list); |
|
||||||
foreach (IProjectContent p in pc.ReferencedContents) { |
|
||||||
AddNamespaceMembersInAssembly(p, xmlNamespace, list); |
|
||||||
} |
|
||||||
return list; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void AddNamespaceMembersInAssembly(IProjectContent projectContent, string xmlNamespace, ArrayList list) |
|
||||||
{ |
|
||||||
foreach (IAttribute att in projectContent.GetAssemblyAttributes()) { |
|
||||||
if (att.PositionalArguments.Count == 2 |
|
||||||
&& att.AttributeType.FullyQualifiedName == "System.Windows.Markup.XmlnsDefinitionAttribute") |
|
||||||
{ |
|
||||||
string namespaceName = att.PositionalArguments[1] as string; |
|
||||||
if (xmlNamespace.Equals(att.PositionalArguments[0]) && namespaceName != null) { |
|
||||||
projectContent.AddNamespaceContents(list, namespaceName, projectContent.Language, false); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,63 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <author name="Daniel Grunwald"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Text; |
|
||||||
using ICSharpCode.SharpDevelop.Dom; |
|
||||||
using ICSharpCode.XmlEditor; |
|
||||||
|
|
||||||
namespace XamlBinding |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Represents the context of a location in a XAML document.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class XamlExpressionContext : ExpressionContext |
|
||||||
{ |
|
||||||
public static readonly XamlExpressionContext Empty = new XamlExpressionContext(new XmlElementPath(), null, false); |
|
||||||
|
|
||||||
public readonly XmlElementPath ElementPath; |
|
||||||
public readonly string AttributeName; |
|
||||||
public readonly bool InAttributeValue; |
|
||||||
|
|
||||||
public XamlExpressionContext(XmlElementPath elementPath, string attributeName, bool inAttributeValue) |
|
||||||
{ |
|
||||||
if (elementPath == null) |
|
||||||
throw new ArgumentNullException("elementPath"); |
|
||||||
this.ElementPath = elementPath; |
|
||||||
this.AttributeName = attributeName; |
|
||||||
this.InAttributeValue = inAttributeValue; |
|
||||||
} |
|
||||||
|
|
||||||
public override bool ShowEntry(object o) |
|
||||||
{ |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
public override string ToString() |
|
||||||
{ |
|
||||||
StringBuilder b = new StringBuilder(); |
|
||||||
b.Append("[XamlExpressionContext "); |
|
||||||
for (int i = 0; i < ElementPath.Elements.Count; i ++) { |
|
||||||
if (i > 0) b.Append(">"); |
|
||||||
if (!string.IsNullOrEmpty(ElementPath.Elements[i].Prefix)) { |
|
||||||
b.Append(ElementPath.Elements[i].Prefix); |
|
||||||
b.Append(':'); |
|
||||||
} |
|
||||||
b.Append(ElementPath.Elements[i].Name); |
|
||||||
} |
|
||||||
if (AttributeName != null) { |
|
||||||
b.Append(" AttributeName="); |
|
||||||
b.Append(AttributeName); |
|
||||||
if (InAttributeValue) { |
|
||||||
b.Append(" InAttributeValue"); |
|
||||||
} |
|
||||||
} |
|
||||||
b.Append("]"); |
|
||||||
return b.ToString(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,74 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <author name="Daniel Grunwald"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Text; |
|
||||||
using System.Xml; |
|
||||||
using ICSharpCode.Core; |
|
||||||
using ICSharpCode.SharpDevelop.Dom; |
|
||||||
using ICSharpCode.XmlEditor; |
|
||||||
|
|
||||||
namespace XamlBinding |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Description of XamlExpressionFinder.
|
|
||||||
/// </summary>
|
|
||||||
public class XamlExpressionFinder : IExpressionFinder |
|
||||||
{ |
|
||||||
public static readonly XamlExpressionFinder Instance = new XamlExpressionFinder(); |
|
||||||
|
|
||||||
bool IsValidChar(char c) |
|
||||||
{ |
|
||||||
return char.IsLetterOrDigit(c) || c == '_' || c == ':' || c == '.'; |
|
||||||
} |
|
||||||
|
|
||||||
public ExpressionResult FindExpression(string text, int offset) |
|
||||||
{ |
|
||||||
int pos = offset - 1; |
|
||||||
while (pos > 0 && IsValidChar(text[pos])) { |
|
||||||
pos--; |
|
||||||
} |
|
||||||
pos++; |
|
||||||
return new ExpressionResult(text.Substring(pos, offset - pos), GetContext(text, offset)); |
|
||||||
} |
|
||||||
|
|
||||||
public ExpressionResult FindFullExpression(string text, int offset) |
|
||||||
{ |
|
||||||
int start = offset - 1; |
|
||||||
while (start > 0 && IsValidChar(text[start])) { |
|
||||||
start--; |
|
||||||
} |
|
||||||
start++; |
|
||||||
while (offset < text.Length && IsValidChar(text[offset])) { |
|
||||||
offset++; |
|
||||||
} |
|
||||||
return new ExpressionResult(text.Substring(start, offset - start), GetContext(text, offset)); |
|
||||||
} |
|
||||||
|
|
||||||
public string RemoveLastPart(string expression) |
|
||||||
{ |
|
||||||
return ""; |
|
||||||
} |
|
||||||
|
|
||||||
ExpressionContext GetContext(string text, int offset) |
|
||||||
{ |
|
||||||
XmlElementPath path = XmlParser.GetActiveElementStartPathAtIndex(text, offset); |
|
||||||
if (path == null || path.Elements.Count == 0) { |
|
||||||
if (offset > 0 && text[offset - 1] == '<') |
|
||||||
return XamlExpressionContext.Empty; |
|
||||||
else |
|
||||||
return ExpressionContext.Default; |
|
||||||
} |
|
||||||
string attributeName = XmlParser.GetAttributeNameAtIndex(text, offset); |
|
||||||
if (!string.IsNullOrEmpty(attributeName)) { |
|
||||||
return new XamlExpressionContext(path, attributeName, XmlParser.IsInsideAttributeValue(text, offset)); |
|
||||||
} else { |
|
||||||
return new XamlExpressionContext(path, null, false); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,142 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <author name="Daniel Grunwald"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.IO; |
|
||||||
using System.Xml; |
|
||||||
using ICSharpCode.Core; |
|
||||||
using ICSharpCode.SharpDevelop.Dom; |
|
||||||
|
|
||||||
namespace XamlBinding |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Parses xaml files to partial classes for the Dom.
|
|
||||||
/// </summary>
|
|
||||||
public class XamlParser : IParser |
|
||||||
{ |
|
||||||
string[] lexerTags; |
|
||||||
|
|
||||||
public string[] LexerTags { |
|
||||||
get { |
|
||||||
return lexerTags; |
|
||||||
} |
|
||||||
set { |
|
||||||
lexerTags = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public LanguageProperties Language { |
|
||||||
get { |
|
||||||
return LanguageProperties.CSharp; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanParse(string fileName) |
|
||||||
{ |
|
||||||
return Path.GetExtension(fileName).Equals(".xaml", StringComparison.OrdinalIgnoreCase); |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanParse(ICSharpCode.SharpDevelop.Project.IProject project) |
|
||||||
{ |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
const string XamlNamespace = "http://schemas.microsoft.com/winfx/2006/xaml"; |
|
||||||
|
|
||||||
public ICompilationUnit Parse(IProjectContent projectContent, string fileName, string fileContent) |
|
||||||
{ |
|
||||||
XamlCompilationUnit cu = new XamlCompilationUnit(projectContent); |
|
||||||
cu.FileName = fileName; |
|
||||||
try { |
|
||||||
using (XmlTextReader r = new XmlTextReader(new StringReader(fileContent))) { |
|
||||||
r.WhitespaceHandling = WhitespaceHandling.Significant; |
|
||||||
r.Read(); |
|
||||||
r.MoveToContent(); |
|
||||||
DomRegion classStart = new DomRegion(r.LineNumber, r.LinePosition - 1); |
|
||||||
string className = r.GetAttribute("Class", XamlNamespace); |
|
||||||
if (string.IsNullOrEmpty(className)) { |
|
||||||
LoggingService.Debug("XamlParser: returning empty cu because root element has no Class attribute"); |
|
||||||
} else { |
|
||||||
DefaultClass c = new DefaultClass(cu, className); |
|
||||||
c.Modifiers = ModifierEnum.Partial; |
|
||||||
c.Region = classStart; |
|
||||||
c.BaseTypes.Add(TypeFromXmlNode(cu, r)); |
|
||||||
cu.Classes.Add(c); |
|
||||||
|
|
||||||
DefaultMethod initializeComponent = new DefaultMethod( |
|
||||||
"InitializeComponent", |
|
||||||
projectContent.SystemTypes.Void, |
|
||||||
ModifierEnum.Public | ModifierEnum.Synthetic, |
|
||||||
classStart, DomRegion.Empty, |
|
||||||
c); |
|
||||||
c.Methods.Add(initializeComponent); |
|
||||||
|
|
||||||
ParseXamlElement(cu, c, r); |
|
||||||
if (r.NodeType == XmlNodeType.EndElement) { |
|
||||||
c.Region = new DomRegion(classStart.BeginLine, classStart.BeginColumn, r.LineNumber, r.LinePosition + r.Name.Length); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} catch (XmlException ex) { |
|
||||||
LoggingService.Debug("XamlParser exception: " + ex.ToString()); |
|
||||||
cu.ErrorsDuringCompile = true; |
|
||||||
} |
|
||||||
return cu; |
|
||||||
} |
|
||||||
|
|
||||||
IReturnType TypeFromXmlNode(XamlCompilationUnit cu, XmlReader r) |
|
||||||
{ |
|
||||||
return cu.CreateType(r.NamespaceURI, r.LocalName); |
|
||||||
} |
|
||||||
|
|
||||||
void ParseXamlElement(XamlCompilationUnit cu, DefaultClass c, XmlTextReader r) |
|
||||||
{ |
|
||||||
Debug.Assert(r.NodeType == XmlNodeType.Element); |
|
||||||
string name = r.GetAttribute("Name", XamlNamespace) ?? r.GetAttribute("Name"); |
|
||||||
bool isEmptyElement = r.IsEmptyElement; |
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(name)) { |
|
||||||
IReturnType type = TypeFromXmlNode(cu, r); |
|
||||||
|
|
||||||
// Use position of Name attribute for field region
|
|
||||||
//if (!r.MoveToAttribute("Name", XamlNamespace)) {
|
|
||||||
// r.MoveToAttribute("Name");
|
|
||||||
//}
|
|
||||||
DomRegion position = new DomRegion(r.LineNumber, r.LinePosition, r.LineNumber, r.LinePosition + name.Length); |
|
||||||
c.Fields.Add(new DefaultField(type, name, ModifierEnum.Internal, position, c)); |
|
||||||
} |
|
||||||
|
|
||||||
if (isEmptyElement) |
|
||||||
return; |
|
||||||
while (r.Read()) { |
|
||||||
if (r.NodeType == XmlNodeType.Element) { |
|
||||||
ParseXamlElement(cu, c, r); |
|
||||||
} else if (r.NodeType == XmlNodeType.Comment) { |
|
||||||
foreach (string tag in lexerTags) { |
|
||||||
if (r.Value.Contains(tag)) { |
|
||||||
cu.TagComments.Add(new TagComment(r.Value, new DomRegion(r.LineNumber, r.LinePosition, r.LineNumber, r.LinePosition + r.Value.Length))); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} else if (r.NodeType == XmlNodeType.EndElement) { |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IExpressionFinder CreateExpressionFinder(string fileName) |
|
||||||
{ |
|
||||||
return XamlExpressionFinder.Instance; |
|
||||||
} |
|
||||||
|
|
||||||
public IResolver CreateResolver() |
|
||||||
{ |
|
||||||
return new XamlResolver(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,336 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <author name="Daniel Grunwald"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using ICSharpCode.XmlEditor; |
|
||||||
using System; |
|
||||||
using System.Collections; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.IO; |
|
||||||
using System.Linq; |
|
||||||
using System.Xml; |
|
||||||
using ICSharpCode.Core; |
|
||||||
using ICSharpCode.SharpDevelop.Dom; |
|
||||||
|
|
||||||
namespace XamlBinding |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Description of XamlResolver.
|
|
||||||
/// </summary>
|
|
||||||
public class XamlResolver : IResolver |
|
||||||
{ |
|
||||||
IClass callingClass; |
|
||||||
string resolveExpression; |
|
||||||
XamlExpressionContext context; |
|
||||||
ParseInformation parseInfo; |
|
||||||
int caretLineNumber, caretColumn; |
|
||||||
|
|
||||||
bool IsReaderAtTarget(XmlTextReader r) |
|
||||||
{ |
|
||||||
if (r.LineNumber > caretLineNumber) |
|
||||||
return true; |
|
||||||
else if (r.LineNumber == caretLineNumber) |
|
||||||
return r.LinePosition >= caretColumn; |
|
||||||
else |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
public ResolveResult Resolve(ExpressionResult expressionResult, ParseInformation parseInfo, string fileContent) |
|
||||||
{ |
|
||||||
this.resolveExpression = expressionResult.Expression; |
|
||||||
this.parseInfo = parseInfo; |
|
||||||
this.caretLineNumber = expressionResult.Region.BeginLine; |
|
||||||
this.caretColumn = expressionResult.Region.BeginColumn; |
|
||||||
this.callingClass = parseInfo.BestCompilationUnit.GetInnermostClass(caretLineNumber, caretColumn); |
|
||||||
this.context = expressionResult.Context as XamlExpressionContext; |
|
||||||
if (context == null) |
|
||||||
return null; |
|
||||||
try { |
|
||||||
using (XmlTextReader r = new XmlTextReader(new StringReader(fileContent))) { |
|
||||||
r.WhitespaceHandling = WhitespaceHandling.Significant; |
|
||||||
// move reader to correct position
|
|
||||||
while (r.Read() && !IsReaderAtTarget(r)) { } |
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(context.AttributeName)) { |
|
||||||
return ResolveElementName(r); |
|
||||||
} else if (context.InAttributeValue) { |
|
||||||
MemberResolveResult mrr = ResolveAttribute(r, context.AttributeName); |
|
||||||
if (mrr != null) { |
|
||||||
return ResolveAttributeValue(mrr.ResolvedMember, resolveExpression); |
|
||||||
} |
|
||||||
} else { |
|
||||||
// in attribute name
|
|
||||||
return ResolveAttribute(r, resolveExpression); |
|
||||||
} |
|
||||||
} |
|
||||||
return null; |
|
||||||
} catch (XmlException) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
ResolveResult ResolveElementName(XmlReader r) |
|
||||||
{ |
|
||||||
string xmlNamespace; |
|
||||||
string name; |
|
||||||
if (resolveExpression.Contains(":")) { |
|
||||||
string prefix = resolveExpression.Substring(0, resolveExpression.IndexOf(':')); |
|
||||||
name = resolveExpression.Substring(resolveExpression.IndexOf(':') + 1); |
|
||||||
xmlNamespace = r.LookupNamespace(prefix); |
|
||||||
} else { |
|
||||||
xmlNamespace = r.LookupNamespace(""); |
|
||||||
name = resolveExpression; |
|
||||||
} |
|
||||||
if (name.Contains(".")) { |
|
||||||
string propertyName = name.Substring(name.IndexOf('.') + 1); |
|
||||||
name = name.Substring(0, name.IndexOf('.')); |
|
||||||
return ResolveProperty(xmlNamespace, name, propertyName, true); |
|
||||||
} else { |
|
||||||
IProjectContent pc = parseInfo.BestCompilationUnit.ProjectContent; |
|
||||||
IReturnType resolvedType = XamlCompilationUnit.FindType(pc, xmlNamespace, name); |
|
||||||
IClass resolvedClass = resolvedType != null ? resolvedType.GetUnderlyingClass() : null; |
|
||||||
if (resolvedClass != null) { |
|
||||||
return new TypeResolveResult(callingClass, null, resolvedClass); |
|
||||||
} else { |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
MemberResolveResult ResolveProperty(string xmlNamespace, string className, string propertyName, bool allowAttached) |
|
||||||
{ |
|
||||||
IProjectContent pc = parseInfo.BestCompilationUnit.ProjectContent; |
|
||||||
IReturnType resolvedType = XamlCompilationUnit.FindType(pc, xmlNamespace, className); |
|
||||||
if (resolvedType != null && resolvedType.GetUnderlyingClass() != null) { |
|
||||||
IMember member = resolvedType.GetProperties().Find(delegate(IProperty p) { return p.Name == propertyName; }); |
|
||||||
if (member == null) { |
|
||||||
member = resolvedType.GetEvents().Find(delegate(IEvent p) { return p.Name == propertyName; }); |
|
||||||
} |
|
||||||
if (member == null && allowAttached) { |
|
||||||
member = resolvedType.GetMethods().Find( |
|
||||||
delegate(IMethod p) { |
|
||||||
return p.IsStatic && p.Parameters.Count == 1 && p.Name == "Get" + propertyName; |
|
||||||
}); |
|
||||||
} |
|
||||||
if (member != null) |
|
||||||
return new MemberResolveResult(callingClass, null, member); |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
MemberResolveResult ResolveAttribute(XmlReader r, string attributeName) |
|
||||||
{ |
|
||||||
if (context.ElementPath.Elements.Count == 0) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
string attributeXmlNamespace; |
|
||||||
if (attributeName.Contains(":")) { |
|
||||||
attributeXmlNamespace = r.LookupNamespace(attributeName.Substring(0, attributeName.IndexOf(':'))); |
|
||||||
attributeName = attributeName.Substring(attributeName.IndexOf(':') + 1); |
|
||||||
} else { |
|
||||||
attributeXmlNamespace = r.LookupNamespace(""); |
|
||||||
} |
|
||||||
if (attributeName.Contains(".")) { |
|
||||||
string className = attributeName.Substring(0, attributeName.IndexOf('.')); |
|
||||||
attributeName = attributeName.Substring(attributeName.IndexOf('.') + 1); |
|
||||||
return ResolveProperty(attributeXmlNamespace, className, attributeName, true); |
|
||||||
} else { |
|
||||||
ICSharpCode.XmlEditor.QualifiedName lastElement = context.ElementPath.Elements[context.ElementPath.Elements.Count - 1]; |
|
||||||
return ResolveProperty(lastElement.Namespace, lastElement.Name, attributeName, false); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
ResolveResult ResolveAttributeValue(IMember propertyOrEvent, string expression) |
|
||||||
{ |
|
||||||
if (propertyOrEvent == null) |
|
||||||
return null; |
|
||||||
if (propertyOrEvent is IEvent) { |
|
||||||
return new MethodGroupResolveResult(callingClass, null, callingClass.DefaultReturnType, expression); |
|
||||||
} |
|
||||||
|
|
||||||
if (propertyOrEvent.Name == "Name" && callingClass != null) { |
|
||||||
foreach (IField f in callingClass.Fields) { |
|
||||||
if (f.Name == expression) |
|
||||||
return new MemberResolveResult(callingClass, null, f); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IReturnType type = propertyOrEvent.ReturnType; |
|
||||||
if (type == null) return null; |
|
||||||
IClass c = type.GetUnderlyingClass(); |
|
||||||
if (c == null) return null; |
|
||||||
|
|
||||||
if (c.ClassType == ClassType.Enum) { |
|
||||||
foreach (IField f in c.Fields) { |
|
||||||
if (f.Name == expression) |
|
||||||
return new MemberResolveResult(callingClass, null, f); |
|
||||||
} |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
public ArrayList CtrlSpace(int caretLineNumber, int caretColumn, ParseInformation parseInfo, string fileContent, ExpressionContext expressionContext) |
|
||||||
{ |
|
||||||
this.parseInfo = parseInfo; |
|
||||||
this.caretLineNumber = caretLineNumber; |
|
||||||
this.caretColumn = caretColumn; |
|
||||||
this.callingClass = parseInfo.BestCompilationUnit.GetInnermostClass(caretLineNumber, caretColumn); |
|
||||||
this.context = expressionContext as XamlExpressionContext; |
|
||||||
if (context == null) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
if (context.AttributeName == null) { |
|
||||||
return CtrlSpaceForElement(fileContent); |
|
||||||
} else if (context.InAttributeValue) { |
|
||||||
return CtrlSpaceForAttributeValue(fileContent, context); |
|
||||||
} else { |
|
||||||
return CtrlSpaceForAttributeName(fileContent, context); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
ArrayList CtrlSpaceForAttributeName(string fileContent, XamlExpressionContext context) |
|
||||||
{ |
|
||||||
if (context.ElementPath.Elements.Count == 0) |
|
||||||
return null; |
|
||||||
QualifiedName lastElement = context.ElementPath.Elements[context.ElementPath.Elements.Count - 1]; |
|
||||||
XamlCompilationUnit cu = parseInfo.BestCompilationUnit as XamlCompilationUnit; |
|
||||||
if (cu == null) |
|
||||||
return null; |
|
||||||
IReturnType rt = cu.CreateType(lastElement.Namespace, lastElement.Name); |
|
||||||
if (rt == null) |
|
||||||
return null; |
|
||||||
ArrayList list = new ArrayList(); |
|
||||||
foreach (IProperty p in rt.GetProperties()) { |
|
||||||
if (p.IsPublic && p.CanSet) { |
|
||||||
list.Add(p); |
|
||||||
} |
|
||||||
} |
|
||||||
return list; |
|
||||||
} |
|
||||||
|
|
||||||
ArrayList CtrlSpaceForAttributeValue(string fileContent, XamlExpressionContext context) |
|
||||||
{ |
|
||||||
ArrayList attributes = CtrlSpaceForAttributeName(fileContent, context); |
|
||||||
if (attributes != null) { |
|
||||||
foreach (IProperty p in attributes.OfType<IProperty>()) { |
|
||||||
if (p.Name == context.AttributeName && p.ReturnType != null) { |
|
||||||
IClass c = p.ReturnType.GetUnderlyingClass(); |
|
||||||
if (c != null && c.ClassType == ClassType.Enum) { |
|
||||||
return EnumCompletion(c); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
ArrayList EnumCompletion(IClass enumClass) |
|
||||||
{ |
|
||||||
ArrayList arr = new ArrayList(); |
|
||||||
foreach (IField f in enumClass.Fields) { |
|
||||||
arr.Add(f); |
|
||||||
} |
|
||||||
return arr; |
|
||||||
} |
|
||||||
|
|
||||||
ArrayList CtrlSpaceForElement(string fileContent) |
|
||||||
{ |
|
||||||
using (XmlTextReader r = new XmlTextReader(new StringReader(fileContent))) { |
|
||||||
try { |
|
||||||
r.WhitespaceHandling = WhitespaceHandling.Significant; |
|
||||||
// move reader to correct position
|
|
||||||
while (r.Read() && !IsReaderAtTarget(r)) { } |
|
||||||
} catch (XmlException) { |
|
||||||
} |
|
||||||
ArrayList result = new ArrayList(); |
|
||||||
IProjectContent pc = parseInfo.BestCompilationUnit.ProjectContent; |
|
||||||
|
|
||||||
resolveExpression = r.Name; |
|
||||||
TypeResolveResult rr = ResolveElementName(r) as TypeResolveResult; |
|
||||||
if (rr != null) { |
|
||||||
AddPropertiesForType(result, r, rr); |
|
||||||
} |
|
||||||
|
|
||||||
foreach (var ns in r.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml)) { |
|
||||||
ArrayList list = XamlCompilationUnit.GetNamespaceMembers(pc, ns.Value); |
|
||||||
if (list != null) { |
|
||||||
foreach (IClass c in list.OfType<IClass>()) { |
|
||||||
if (c.ClassType != ClassType.Class) |
|
||||||
continue; |
|
||||||
if (c.IsAbstract && c.IsStatic) |
|
||||||
continue; |
|
||||||
if (c.ClassInheritanceTree.Any(b => b.FullyQualifiedName == "System.Attribute")) |
|
||||||
continue; |
|
||||||
if (!c.Methods.Any(m => m.IsConstructor && m.IsPublic)) |
|
||||||
continue; |
|
||||||
if (string.IsNullOrEmpty(ns.Key)) |
|
||||||
result.Add(c); |
|
||||||
else |
|
||||||
result.Add(new XamlCompletionClass(c, ns.Key)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return result; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void AddPropertiesForType(ArrayList result, XmlTextReader r, TypeResolveResult rr) |
|
||||||
{ |
|
||||||
if (rr.ResolvedType != null) { |
|
||||||
foreach (IProperty p in rr.ResolvedType.GetProperties()) { |
|
||||||
if (!p.IsPublic) |
|
||||||
continue; |
|
||||||
if (!p.CanSet && !IsCollectionType(p.ReturnType)) |
|
||||||
continue; |
|
||||||
string propPrefix = p.DeclaringType.Name; |
|
||||||
if (!string.IsNullOrEmpty(r.Prefix)) |
|
||||||
propPrefix = r.Prefix + ":" + propPrefix; |
|
||||||
result.Add(new XamlCompletionProperty(p, propPrefix)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool IsCollectionType(IReturnType rt) |
|
||||||
{ |
|
||||||
if (rt == null) |
|
||||||
return false; |
|
||||||
return rt.GetMethods().Any(m => m.Name == "Add" && m.IsPublic); |
|
||||||
} |
|
||||||
|
|
||||||
class XamlCompletionClass : DefaultClass, IEntity |
|
||||||
{ |
|
||||||
string newName; |
|
||||||
|
|
||||||
public XamlCompletionClass(IClass baseClass, string prefix) |
|
||||||
: base(baseClass.CompilationUnit, baseClass.FullyQualifiedName) |
|
||||||
{ |
|
||||||
this.Modifiers = baseClass.Modifiers; |
|
||||||
newName = prefix + ":" + baseClass.Name; |
|
||||||
} |
|
||||||
|
|
||||||
string IEntity.Name { |
|
||||||
get { return newName; } |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class XamlCompletionProperty : DefaultProperty, IEntity |
|
||||||
{ |
|
||||||
string newName; |
|
||||||
|
|
||||||
public XamlCompletionProperty(IProperty baseProperty, string prefix) |
|
||||||
: base(baseProperty.DeclaringType, baseProperty.Name) |
|
||||||
{ |
|
||||||
this.Modifiers = baseProperty.Modifiers; |
|
||||||
newName = prefix + "." + baseProperty.Name; |
|
||||||
} |
|
||||||
|
|
||||||
string IEntity.Name { |
|
||||||
get { return newName; } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,43 +0,0 @@ |
|||||||
<AddIn name = "XAML binding" |
|
||||||
author = "Daniel Grunwald" |
|
||||||
copyright = "prj:///doc/copyright.txt" |
|
||||||
url = "http://icsharpcode.net" |
|
||||||
description = "Enables code-completion for xaml files."> |
|
||||||
|
|
||||||
<!-- |
|
||||||
This file is unrelated to the WPF Designer, it is a language binding for .xaml files. |
|
||||||
It allows using Go to definition, find references, code completion in .xaml files. |
|
||||||
--> |
|
||||||
|
|
||||||
<Manifest> |
|
||||||
<Identity name = "ICSharpCode.XamlBinding"/> |
|
||||||
<Dependency addin = "ICSharpCode.XmlEditor" requirePreload = "true"/> |
|
||||||
</Manifest> |
|
||||||
|
|
||||||
<Runtime> |
|
||||||
<Import assembly = "XamlBinding.dll"/> |
|
||||||
</Runtime> |
|
||||||
|
|
||||||
<Path name = "/Workspace/Icons"> |
|
||||||
<Icon id = "XamlFileIcon" |
|
||||||
extensions = ".xaml" |
|
||||||
resource = "FileIcons.XmlIcon" /> |
|
||||||
</Path> |
|
||||||
|
|
||||||
<Path name = "/SharpDevelop/Workbench/FileFilter"> |
|
||||||
<FileFilter id = "Xaml" |
|
||||||
insertbefore="AllFiles" |
|
||||||
name = "Xaml files (*.xaml)" |
|
||||||
extensions = "*.xaml"/> |
|
||||||
</Path> |
|
||||||
|
|
||||||
<Path name = "/Workspace/Parser"> |
|
||||||
<Parser id = "XAML" |
|
||||||
supportedextensions = ".xaml" |
|
||||||
class = "XamlBinding.XamlParser"/> |
|
||||||
</Path> |
|
||||||
|
|
||||||
<Path name = "/AddIns/DefaultTextEditor/CodeCompletion"> |
|
||||||
<CodeCompletionBinding id = "Xaml" extensions = ".xaml" class = "XamlBinding.XamlCodeCompletionBinding"/> |
|
||||||
</Path> |
|
||||||
</AddIn> |
|
||||||
@ -1,94 +0,0 @@ |
|||||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> |
|
||||||
<PropertyGroup> |
|
||||||
<ProjectGuid>{7C96B65D-28A5-4F28-A35B-8D83CE831EE8}</ProjectGuid> |
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|
||||||
<OutputType>Library</OutputType> |
|
||||||
<RootNamespace>XamlBinding</RootNamespace> |
|
||||||
<AssemblyName>XamlBinding</AssemblyName> |
|
||||||
<OutputPath>..\..\..\..\..\AddIns\AddIns\BackendBindings\XamlBinding</OutputPath> |
|
||||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
|
||||||
<NoStdLib>False</NoStdLib> |
|
||||||
<WarningLevel>4</WarningLevel> |
|
||||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
|
||||||
<SourceAnalysisOverrideSettingsFile>C:\Users\Daniel\AppData\Roaming\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile> |
|
||||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> |
|
||||||
</PropertyGroup> |
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
|
||||||
<DebugSymbols>true</DebugSymbols> |
|
||||||
<DebugType>Full</DebugType> |
|
||||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
|
||||||
<Optimize>False</Optimize> |
|
||||||
</PropertyGroup> |
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
|
||||||
<DebugSymbols>False</DebugSymbols> |
|
||||||
<DebugType>None</DebugType> |
|
||||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
|
||||||
<DefineConstants>TRACE</DefineConstants> |
|
||||||
</PropertyGroup> |
|
||||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> |
|
||||||
<RegisterForComInterop>False</RegisterForComInterop> |
|
||||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
|
||||||
<BaseAddress>4194304</BaseAddress> |
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget> |
|
||||||
<FileAlignment>4096</FileAlignment> |
|
||||||
</PropertyGroup> |
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
|
||||||
<ItemGroup> |
|
||||||
<Reference Include="System" /> |
|
||||||
<Reference Include="System.Core"> |
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
|
||||||
</Reference> |
|
||||||
<Reference Include="System.Windows.Forms" /> |
|
||||||
<Reference Include="System.Xml" /> |
|
||||||
</ItemGroup> |
|
||||||
<ItemGroup> |
|
||||||
<Folder Include="Configuration" /> |
|
||||||
<Folder Include="Src" /> |
|
||||||
<None Include="XamlBinding.addin"> |
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
|
||||||
</None> |
|
||||||
<Compile Include="..\..\..\..\Main\GlobalAssemblyInfo.cs"> |
|
||||||
<Link>Configuration\GlobalAssemblyInfo.cs</Link> |
|
||||||
</Compile> |
|
||||||
<Compile Include="Configuration\AssemblyInfo.cs" /> |
|
||||||
<Compile Include="Src\XamlClassReturnType.cs" /> |
|
||||||
<Compile Include="Src\XamlCodeCompletionBinding.cs" /> |
|
||||||
<Compile Include="Src\XamlCompilationUnit.cs" /> |
|
||||||
<Compile Include="Src\XamlExpressionContext.cs" /> |
|
||||||
<Compile Include="Src\XamlExpressionFinder.cs" /> |
|
||||||
<Compile Include="Src\XamlParser.cs" /> |
|
||||||
<Compile Include="Src\XamlResolver.cs" /> |
|
||||||
<ProjectReference Include="..\..\..\..\Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj"> |
|
||||||
<Project>{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}</Project> |
|
||||||
<Name>ICSharpCode.TextEditor</Name> |
|
||||||
<Private>False</Private> |
|
||||||
</ProjectReference> |
|
||||||
<ProjectReference Include="..\..\..\..\Libraries\NRefactory\Project\NRefactory.csproj"> |
|
||||||
<Project>{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}</Project> |
|
||||||
<Name>NRefactory</Name> |
|
||||||
<Private>False</Private> |
|
||||||
</ProjectReference> |
|
||||||
<ProjectReference Include="..\..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj"> |
|
||||||
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project> |
|
||||||
<Name>ICSharpCode.SharpDevelop</Name> |
|
||||||
<Private>False</Private> |
|
||||||
</ProjectReference> |
|
||||||
<ProjectReference Include="..\..\..\..\Main\Core\Project\ICSharpCode.Core.csproj"> |
|
||||||
<Project>{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}</Project> |
|
||||||
<Name>ICSharpCode.Core</Name> |
|
||||||
<Private>False</Private> |
|
||||||
</ProjectReference> |
|
||||||
<ProjectReference Include="..\..\..\..\Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj"> |
|
||||||
<Project>{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}</Project> |
|
||||||
<Name>ICSharpCode.SharpDevelop.Dom</Name> |
|
||||||
<Private>False</Private> |
|
||||||
</ProjectReference> |
|
||||||
<ProjectReference Include="..\..\..\DisplayBindings\XmlEditor\Project\XmlEditor.csproj"> |
|
||||||
<Project>{6B717BD1-CD5E-498C-A42E-9E6A4584DC48}</Project> |
|
||||||
<Name>XmlEditor</Name> |
|
||||||
<Private>False</Private> |
|
||||||
</ProjectReference> |
|
||||||
</ItemGroup> |
|
||||||
</Project> |
|
||||||
@ -1,16 +0,0 @@ |
|||||||
#region Using directives
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Reflection; |
|
||||||
using System.Runtime.InteropServices; |
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("XamlBinding.Tests")] |
|
||||||
[assembly: AssemblyDescription("")] |
|
||||||
[assembly: AssemblyConfiguration("")] |
|
||||||
[assembly: AssemblyTrademark("")] |
|
||||||
[assembly: AssemblyCulture("")] |
|
||||||
@ -1,75 +0,0 @@ |
|||||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|
||||||
<PropertyGroup> |
|
||||||
<ProjectGuid>{F390DA70-1FE1-4715-81A0-389AB010C130}</ProjectGuid> |
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|
||||||
<OutputType>Library</OutputType> |
|
||||||
<RootNamespace>XamlBinding.Tests</RootNamespace> |
|
||||||
<AssemblyName>XamlBinding.Tests</AssemblyName> |
|
||||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> |
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder> |
|
||||||
<SourceAnalysisOverrideSettingsFile>C:\Users\Daniel\AppData\Roaming\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile> |
|
||||||
<OutputPath>..\..\..\..\..\bin\UnitTests\</OutputPath> |
|
||||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
|
||||||
<NoStdLib>False</NoStdLib> |
|
||||||
<WarningLevel>4</WarningLevel> |
|
||||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
|
||||||
</PropertyGroup> |
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
|
||||||
<DebugSymbols>true</DebugSymbols> |
|
||||||
<DebugType>Full</DebugType> |
|
||||||
<Optimize>False</Optimize> |
|
||||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
|
||||||
</PropertyGroup> |
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
|
||||||
<DebugSymbols>False</DebugSymbols> |
|
||||||
<DebugType>None</DebugType> |
|
||||||
<Optimize>True</Optimize> |
|
||||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
|
||||||
<DefineConstants>TRACE</DefineConstants> |
|
||||||
</PropertyGroup> |
|
||||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> |
|
||||||
<RegisterForComInterop>False</RegisterForComInterop> |
|
||||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> |
|
||||||
<BaseAddress>4194304</BaseAddress> |
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget> |
|
||||||
<FileAlignment>4096</FileAlignment> |
|
||||||
</PropertyGroup> |
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
|
||||||
<ItemGroup> |
|
||||||
<Reference Include="nunit.framework"> |
|
||||||
<HintPath>..\..\..\..\Tools\NUnit\nunit.framework.dll</HintPath> |
|
||||||
<Private>False</Private> |
|
||||||
</Reference> |
|
||||||
<Reference Include="System" /> |
|
||||||
<Reference Include="System.Core"> |
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
|
||||||
</Reference> |
|
||||||
<Reference Include="System.Xml" /> |
|
||||||
<Reference Include="System.Xml.Linq"> |
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
|
||||||
</Reference> |
|
||||||
</ItemGroup> |
|
||||||
<ItemGroup> |
|
||||||
<Compile Include="..\..\..\..\Main\GlobalAssemblyInfo.cs"> |
|
||||||
<Link>Properties\GlobalAssemblyInfo.cs</Link> |
|
||||||
</Compile> |
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
|
||||||
<Compile Include="XamlExpressionFinderTests.cs" /> |
|
||||||
</ItemGroup> |
|
||||||
<ItemGroup> |
|
||||||
<ProjectReference Include="..\..\..\..\Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj"> |
|
||||||
<Project>{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}</Project> |
|
||||||
<Name>ICSharpCode.SharpDevelop.Dom</Name> |
|
||||||
</ProjectReference> |
|
||||||
<ProjectReference Include="..\..\..\DisplayBindings\XmlEditor\Project\XmlEditor.csproj"> |
|
||||||
<Project>{6B717BD1-CD5E-498C-A42E-9E6A4584DC48}</Project> |
|
||||||
<Name>XmlEditor</Name> |
|
||||||
</ProjectReference> |
|
||||||
<ProjectReference Include="..\Project\XamlBinding.csproj"> |
|
||||||
<Project>{7C96B65D-28A5-4F28-A35B-8D83CE831EE8}</Project> |
|
||||||
<Name>XamlBinding</Name> |
|
||||||
</ProjectReference> |
|
||||||
</ItemGroup> |
|
||||||
</Project> |
|
||||||
@ -1,48 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <author name="Daniel Grunwald"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
|
|
||||||
using ICSharpCode.SharpDevelop.Dom; |
|
||||||
using System; |
|
||||||
using NUnit.Framework; |
|
||||||
using NUnit.Framework.SyntaxHelpers; |
|
||||||
|
|
||||||
namespace XamlBinding.Tests |
|
||||||
{ |
|
||||||
[TestFixture] |
|
||||||
public class XamlExpressionFinderTests |
|
||||||
{ |
|
||||||
XamlExpressionContext GetXamlContext(string text) |
|
||||||
{ |
|
||||||
return (XamlExpressionContext)GetContext(text); |
|
||||||
} |
|
||||||
|
|
||||||
ExpressionContext GetContext(string text) |
|
||||||
{ |
|
||||||
return XamlExpressionFinder.Instance.FindExpression(text, text.Length).Context; |
|
||||||
} |
|
||||||
|
|
||||||
[Test] |
|
||||||
public void FindContextAfterElementName() |
|
||||||
{ |
|
||||||
XamlExpressionContext c = GetXamlContext("<Window><Grid"); |
|
||||||
Assert.AreEqual(2, c.ElementPath.Elements.Count); |
|
||||||
Assert.AreEqual("Window > Grid", c.ElementPath.ToString()); |
|
||||||
Assert.IsNull(c.AttributeName); |
|
||||||
Assert.IsFalse(c.InAttributeValue); |
|
||||||
} |
|
||||||
|
|
||||||
[Test] |
|
||||||
public void FindContextAtElementStart() |
|
||||||
{ |
|
||||||
XamlExpressionContext c = GetXamlContext("<Window><"); |
|
||||||
Assert.AreEqual(0, c.ElementPath.Elements.Count); |
|
||||||
Assert.IsNull(c.AttributeName); |
|
||||||
Assert.IsFalse(c.InAttributeValue); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,245 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Media.Media3D; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Windows.Media.Animation; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Automation; |
|
||||||
using System.Windows.Media.Effects; |
|
||||||
using System.Windows.Navigation; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer |
|
||||||
{ |
|
||||||
public static class BasicMetadata |
|
||||||
{ |
|
||||||
static bool registered; |
|
||||||
|
|
||||||
public static void Register() |
|
||||||
{ |
|
||||||
if (registered) return; |
|
||||||
registered = true; |
|
||||||
|
|
||||||
Metadata.AddStandardValues(typeof(Brush), typeof(Brushes)); |
|
||||||
Metadata.AddStandardValues(typeof(Color), typeof(Colors)); |
|
||||||
Metadata.AddStandardValues(typeof(FontStretch), typeof(FontStretches)); |
|
||||||
Metadata.AddStandardValues(typeof(FontWeight), typeof(FontWeights)); |
|
||||||
Metadata.AddStandardValues(typeof(FontStyle), typeof(FontStyles)); |
|
||||||
Metadata.AddStandardValues(typeof(Cursor), typeof(Cursors)); |
|
||||||
Metadata.AddStandardValues(typeof(PixelFormat), typeof(PixelFormats)); |
|
||||||
Metadata.AddStandardValues(typeof(TextDecorationCollection), typeof(TextDecorations)); |
|
||||||
Metadata.AddStandardValues(typeof(FontFamily), Fonts.SystemFontFamilies); |
|
||||||
|
|
||||||
Metadata.AddStandardValues(typeof(ICommand), typeof(ApplicationCommands)); |
|
||||||
Metadata.AddStandardValues(typeof(ICommand), typeof(EditingCommands)); |
|
||||||
Metadata.AddStandardValues(typeof(ICommand), typeof(NavigationCommands)); |
|
||||||
Metadata.AddStandardValues(typeof(ICommand), typeof(ComponentCommands)); |
|
||||||
Metadata.AddStandardValues(typeof(ICommand), typeof(MediaCommands)); |
|
||||||
|
|
||||||
Metadata.AddPopularProperty(Line.Y2Property); |
|
||||||
Metadata.AddPopularProperty(NavigationWindow.ShowsNavigationUIProperty); |
|
||||||
Metadata.AddPopularProperty(FlowDocumentScrollViewer.DocumentProperty); |
|
||||||
Metadata.AddPopularProperty(GridViewRowPresenterBase.ColumnsProperty); |
|
||||||
Metadata.AddPopularProperty(ListView.ViewProperty); |
|
||||||
Metadata.AddPopularProperty(DocumentPageView.PageNumberProperty); |
|
||||||
Metadata.AddPopularProperty(Popup.PlacementProperty); |
|
||||||
Metadata.AddPopularProperty(Popup.PopupAnimationProperty); |
|
||||||
Metadata.AddPopularProperty(ScrollBar.ViewportSizeProperty); |
|
||||||
Metadata.AddPopularProperty(UniformGrid.RowsProperty); |
|
||||||
Metadata.AddPopularProperty(TabControl.TabStripPlacementProperty); |
|
||||||
Metadata.AddPopularProperty(Line.X1Property); |
|
||||||
Metadata.AddPopularProperty(Line.Y1Property); |
|
||||||
Metadata.AddPopularProperty(Line.X2Property); |
|
||||||
Metadata.AddPopularProperty(Polygon.PointsProperty); |
|
||||||
Metadata.AddPopularProperty(Polyline.PointsProperty); |
|
||||||
Metadata.AddPopularProperty(Path.DataProperty); |
|
||||||
Metadata.AddPopularProperty(HeaderedContentControl.HeaderProperty); |
|
||||||
Metadata.AddPopularProperty(MediaElement.UnloadedBehaviorProperty); |
|
||||||
Metadata.AddPopularProperty(Shape.FillProperty); |
|
||||||
Metadata.AddPopularProperty(Page.TitleProperty); |
|
||||||
Metadata.AddPopularProperty(ItemsControl.ItemsSourceProperty); |
|
||||||
Metadata.AddPopularProperty(Image.SourceProperty); |
|
||||||
Metadata.AddPopularProperty(TextBlock.TextProperty); |
|
||||||
Metadata.AddPopularProperty(DockPanel.LastChildFillProperty); |
|
||||||
Metadata.AddPopularProperty(Expander.IsExpandedProperty); |
|
||||||
Metadata.AddPopularProperty(Shape.StrokeProperty); |
|
||||||
Metadata.AddPopularProperty(RangeBase.ValueProperty); |
|
||||||
Metadata.AddPopularProperty(ItemsControl.ItemContainerStyleProperty); |
|
||||||
Metadata.AddPopularProperty(ToggleButton.IsCheckedProperty); |
|
||||||
Metadata.AddPopularProperty(Window.TitleProperty); |
|
||||||
Metadata.AddPopularProperty(Viewport3DVisual.CameraProperty); |
|
||||||
Metadata.AddPopularProperty(Frame.SourceProperty); |
|
||||||
Metadata.AddPopularProperty(Rectangle.RadiusXProperty); |
|
||||||
Metadata.AddPopularProperty(Rectangle.RadiusYProperty); |
|
||||||
Metadata.AddPopularProperty(FrameworkElement.HeightProperty); |
|
||||||
Metadata.AddPopularProperty(FrameworkElement.WidthProperty); |
|
||||||
Metadata.AddPopularProperty(UniformGrid.ColumnsProperty); |
|
||||||
Metadata.AddPopularProperty(RangeBase.MinimumProperty); |
|
||||||
Metadata.AddPopularProperty(RangeBase.MaximumProperty); |
|
||||||
Metadata.AddPopularProperty(ScrollBar.OrientationProperty); |
|
||||||
Metadata.AddPopularProperty(ContentControl.ContentProperty); |
|
||||||
Metadata.AddPopularProperty(Popup.IsOpenProperty); |
|
||||||
Metadata.AddPopularProperty(TextElement.FontSizeProperty); |
|
||||||
Metadata.AddPopularProperty(FrameworkElement.NameProperty); |
|
||||||
Metadata.AddPopularProperty(Popup.HorizontalOffsetProperty); |
|
||||||
Metadata.AddPopularProperty(Popup.VerticalOffsetProperty); |
|
||||||
Metadata.AddPopularProperty(Window.WindowStyleProperty); |
|
||||||
Metadata.AddPopularProperty(Shape.StrokeThicknessProperty); |
|
||||||
Metadata.AddPopularProperty(TextElement.ForegroundProperty); |
|
||||||
Metadata.AddPopularProperty(FrameworkElement.VerticalAlignmentProperty); |
|
||||||
Metadata.AddPopularProperty(Button.IsDefaultProperty); |
|
||||||
Metadata.AddPopularProperty(UIElement.RenderTransformOriginProperty); |
|
||||||
Metadata.AddPopularProperty(TextElement.FontFamilyProperty); |
|
||||||
Metadata.AddPopularProperty(FrameworkElement.HorizontalAlignmentProperty); |
|
||||||
Metadata.AddPopularProperty(ToolBar.BandProperty); |
|
||||||
Metadata.AddPopularProperty(ToolBar.BandIndexProperty); |
|
||||||
Metadata.AddPopularProperty(ItemsControl.ItemTemplateProperty); |
|
||||||
Metadata.AddPopularProperty(TextBlock.TextWrappingProperty); |
|
||||||
Metadata.AddPopularProperty(FrameworkElement.MarginProperty); |
|
||||||
Metadata.AddPopularProperty(RangeBase.LargeChangeProperty); |
|
||||||
Metadata.AddPopularProperty(RangeBase.SmallChangeProperty); |
|
||||||
Metadata.AddPopularProperty(Panel.BackgroundProperty); |
|
||||||
Metadata.AddPopularProperty(Shape.StrokeMiterLimitProperty); |
|
||||||
Metadata.AddPopularProperty(TextElement.FontWeightProperty); |
|
||||||
Metadata.AddPopularProperty(StackPanel.OrientationProperty); |
|
||||||
Metadata.AddPopularProperty(ListBox.SelectionModeProperty); |
|
||||||
Metadata.AddPopularProperty(FrameworkElement.StyleProperty); |
|
||||||
Metadata.AddPopularProperty(TextBox.TextProperty); |
|
||||||
Metadata.AddPopularProperty(Window.SizeToContentProperty); |
|
||||||
Metadata.AddPopularProperty(Window.ResizeModeProperty); |
|
||||||
Metadata.AddPopularProperty(TextBlock.TextTrimmingProperty); |
|
||||||
Metadata.AddPopularProperty(Window.ShowInTaskbarProperty); |
|
||||||
Metadata.AddPopularProperty(Window.IconProperty); |
|
||||||
Metadata.AddPopularProperty(UIElement.RenderTransformProperty); |
|
||||||
Metadata.AddPopularProperty(Button.IsCancelProperty); |
|
||||||
Metadata.AddPopularProperty(Border.BorderBrushProperty); |
|
||||||
Metadata.AddPopularProperty(Block.TextAlignmentProperty); |
|
||||||
Metadata.AddPopularProperty(Border.CornerRadiusProperty); |
|
||||||
Metadata.AddPopularProperty(Border.BorderThicknessProperty); |
|
||||||
Metadata.AddPopularProperty(TreeViewItem.IsSelectedProperty); |
|
||||||
Metadata.AddPopularProperty(Border.PaddingProperty); |
|
||||||
Metadata.AddPopularProperty(Shape.StretchProperty); |
|
||||||
|
|
||||||
Metadata.AddPopularProperty(typeof(Binding), "Path"); |
|
||||||
Metadata.AddPopularProperty(typeof(Binding), "Source"); |
|
||||||
Metadata.AddPopularProperty(typeof(Binding), "Mode"); |
|
||||||
Metadata.AddPopularProperty(typeof(Binding), "RelativeSource"); |
|
||||||
Metadata.AddPopularProperty(typeof(Binding), "ElementName"); |
|
||||||
Metadata.AddPopularProperty(typeof(Binding), "Converter"); |
|
||||||
Metadata.AddPopularProperty(typeof(Binding), "XPath"); |
|
||||||
|
|
||||||
Metadata.AddValueRange(Block.LineHeightProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Canvas.BottomProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Canvas.LeftProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Canvas.TopProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Canvas.RightProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(ColumnDefinition.MaxWidthProperty, 0, double.PositiveInfinity); |
|
||||||
Metadata.AddValueRange(DocumentViewer.MaxPagesAcrossProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Figure.HorizontalOffsetProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Figure.VerticalOffsetProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(FlowDocument.MaxPageWidthProperty, 0, double.PositiveInfinity); |
|
||||||
Metadata.AddValueRange(FlowDocument.MaxPageHeightProperty, 0, double.PositiveInfinity); |
|
||||||
Metadata.AddValueRange(FlowDocumentPageViewer.ZoomProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(FlowDocumentPageViewer.ZoomIncrementProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(FlowDocumentPageViewer.MinZoomProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(FlowDocumentPageViewer.MaxZoomProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(FrameworkElement.MaxHeightProperty, 0, double.PositiveInfinity); |
|
||||||
Metadata.AddValueRange(FrameworkElement.MaxWidthProperty, 0, double.PositiveInfinity); |
|
||||||
Metadata.AddValueRange(Grid.ColumnSpanProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Grid.RowSpanProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(GridSplitter.KeyboardIncrementProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(GridSplitter.DragIncrementProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(InkCanvas.BottomProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(InkCanvas.TopProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(InkCanvas.RightProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(InkCanvas.LeftProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Line.Y2Property, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Line.X1Property, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Line.Y1Property, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Line.X2Property, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(List.MarkerOffsetProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(List.StartIndexProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Paragraph.TextIndentProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(RangeBase.ValueProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(RangeBase.MaximumProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(RangeBase.MinimumProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(RepeatButton.IntervalProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(RowDefinition.MaxHeightProperty, 0, double.PositiveInfinity); |
|
||||||
Metadata.AddValueRange(Selector.SelectedIndexProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Slider.TickFrequencyProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Slider.SelectionStartProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Slider.SelectionEndProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(TableCell.RowSpanProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(TableCell.ColumnSpanProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(TextBox.MinLinesProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(TextBox.MaxLinesProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(TextBoxBase.UndoLimitProperty, double.MinValue, double.MaxValue); |
|
||||||
Metadata.AddValueRange(TextElement.FontSizeProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Timeline.SpeedRatioProperty, double.Epsilon, double.MaxValue); |
|
||||||
Metadata.AddValueRange(Timeline.DecelerationRatioProperty, 0, 1); |
|
||||||
Metadata.AddValueRange(Timeline.AccelerationRatioProperty, 0, 1); |
|
||||||
Metadata.AddValueRange(Track.ViewportSizeProperty, 0, double.PositiveInfinity); |
|
||||||
Metadata.AddValueRange(UIElement.OpacityProperty, 0, 1); |
|
||||||
|
|
||||||
Metadata.HideProperty(typeof(UIElement), "RenderSize"); |
|
||||||
Metadata.HideProperty(FrameworkElement.NameProperty); |
|
||||||
Metadata.HideProperty(typeof(FrameworkElement), "Resources"); |
|
||||||
Metadata.HideProperty(typeof(Window), "Owner"); |
|
||||||
|
|
||||||
//Metadata.DisablePlacement(typeof(Button));
|
|
||||||
|
|
||||||
Metadata.AddPopularControl(typeof(Button)); |
|
||||||
Metadata.AddPopularControl(typeof(CheckBox)); |
|
||||||
Metadata.AddPopularControl(typeof(ComboBox)); |
|
||||||
Metadata.AddPopularControl(typeof(Label)); |
|
||||||
Metadata.AddPopularControl(typeof(TextBox)); |
|
||||||
Metadata.AddPopularControl(typeof(RadioButton)); |
|
||||||
Metadata.AddPopularControl(typeof(Canvas)); |
|
||||||
Metadata.AddPopularControl(typeof(Grid)); |
|
||||||
Metadata.AddPopularControl(typeof(Border)); |
|
||||||
Metadata.AddPopularControl(typeof(DockPanel)); |
|
||||||
Metadata.AddPopularControl(typeof(Expander)); |
|
||||||
Metadata.AddPopularControl(typeof(GroupBox)); |
|
||||||
Metadata.AddPopularControl(typeof(Image)); |
|
||||||
Metadata.AddPopularControl(typeof(InkCanvas)); |
|
||||||
Metadata.AddPopularControl(typeof(ListBox)); |
|
||||||
Metadata.AddPopularControl(typeof(ListView)); |
|
||||||
Metadata.AddPopularControl(typeof(Menu)); |
|
||||||
Metadata.AddPopularControl(typeof(PasswordBox)); |
|
||||||
Metadata.AddPopularControl(typeof(ProgressBar)); |
|
||||||
Metadata.AddPopularControl(typeof(RichTextBox)); |
|
||||||
Metadata.AddPopularControl(typeof(ScrollViewer)); |
|
||||||
Metadata.AddPopularControl(typeof(Slider)); |
|
||||||
Metadata.AddPopularControl(typeof(StackPanel)); |
|
||||||
Metadata.AddPopularControl(typeof(TabControl)); |
|
||||||
Metadata.AddPopularControl(typeof(ToolBar)); |
|
||||||
Metadata.AddPopularControl(typeof(TreeView)); |
|
||||||
Metadata.AddPopularControl(typeof(Viewbox)); |
|
||||||
Metadata.AddPopularControl(typeof(Viewport3D)); |
|
||||||
Metadata.AddPopularControl(typeof(WrapPanel)); |
|
||||||
|
|
||||||
Metadata.AddDefaultSize(typeof(UIElement), new Size(120, 100)); |
|
||||||
Metadata.AddDefaultSize(typeof(ContentControl), new Size(double.NaN, double.NaN)); |
|
||||||
Metadata.AddDefaultSize(typeof(Button), new Size(75, 23)); |
|
||||||
|
|
||||||
var s1 = new Size(120, double.NaN); |
|
||||||
Metadata.AddDefaultSize(typeof(Slider), s1); |
|
||||||
Metadata.AddDefaultSize(typeof(TextBox), s1); |
|
||||||
Metadata.AddDefaultSize(typeof(PasswordBox), s1); |
|
||||||
Metadata.AddDefaultSize(typeof(ComboBox), s1); |
|
||||||
Metadata.AddDefaultSize(typeof(ProgressBar), s1); |
|
||||||
|
|
||||||
var s2 = new Size(120, 20); |
|
||||||
Metadata.AddDefaultSize(typeof(ToolBar), s2); |
|
||||||
Metadata.AddDefaultSize(typeof(Menu), s2); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,109 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows.Markup; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Reflection; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer |
|
||||||
{ |
|
||||||
public class CallExtension : MarkupExtension |
|
||||||
{ |
|
||||||
public CallExtension(string methodName) |
|
||||||
{ |
|
||||||
this.methodName = methodName; |
|
||||||
} |
|
||||||
|
|
||||||
string methodName; |
|
||||||
|
|
||||||
public override object ProvideValue(IServiceProvider sp) |
|
||||||
{ |
|
||||||
var t = (IProvideValueTarget)sp.GetService(typeof(IProvideValueTarget)); |
|
||||||
return new CallCommand(t.TargetObject as FrameworkElement, methodName); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class CallCommand : DependencyObject, ICommand |
|
||||||
{ |
|
||||||
public CallCommand(FrameworkElement element, string methodName) |
|
||||||
{ |
|
||||||
this.element = element; |
|
||||||
this.methodName = methodName; |
|
||||||
element.DataContextChanged += target_DataContextChanged; |
|
||||||
|
|
||||||
BindingOperations.SetBinding(this, CanCallProperty, new Binding("DataContext.Can" + methodName) { |
|
||||||
Source = element |
|
||||||
}); |
|
||||||
|
|
||||||
GetMethod(); |
|
||||||
} |
|
||||||
|
|
||||||
FrameworkElement element; |
|
||||||
string methodName; |
|
||||||
MethodInfo method; |
|
||||||
|
|
||||||
public static readonly DependencyProperty CanCallProperty = |
|
||||||
DependencyProperty.Register("CanCall", typeof(bool), typeof(CallCommand), |
|
||||||
new PropertyMetadata(true)); |
|
||||||
|
|
||||||
public bool CanCall { |
|
||||||
get { return (bool)GetValue(CanCallProperty); } |
|
||||||
set { SetValue(CanCallProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public object DataContext { |
|
||||||
get { return element.DataContext; } |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
base.OnPropertyChanged(e); |
|
||||||
|
|
||||||
if (e.Property == CanCallProperty) { |
|
||||||
RaiseCanExecuteChanged(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void GetMethod() |
|
||||||
{ |
|
||||||
if (DataContext == null) { |
|
||||||
method = null; |
|
||||||
} |
|
||||||
else { |
|
||||||
method = DataContext.GetType().GetMethod(methodName, Type.EmptyTypes); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void target_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
GetMethod(); |
|
||||||
RaiseCanExecuteChanged(); |
|
||||||
} |
|
||||||
|
|
||||||
void RaiseCanExecuteChanged() |
|
||||||
{ |
|
||||||
if (CanExecuteChanged != null) { |
|
||||||
CanExecuteChanged(this, EventArgs.Empty); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#region ICommand Members
|
|
||||||
|
|
||||||
public event EventHandler CanExecuteChanged; |
|
||||||
|
|
||||||
public bool CanExecute(object parameter) |
|
||||||
{ |
|
||||||
return method != null && CanCall; |
|
||||||
} |
|
||||||
|
|
||||||
public void Execute(object parameter) |
|
||||||
{ |
|
||||||
method.Invoke(DataContext, null); |
|
||||||
} |
|
||||||
|
|
||||||
#endregion
|
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,50 +0,0 @@ |
|||||||
#region Using directives
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Reflection; |
|
||||||
using System.Runtime.CompilerServices; |
|
||||||
using System.Resources; |
|
||||||
using System.Globalization; |
|
||||||
using System.Windows; |
|
||||||
using System.Runtime.InteropServices; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
using System.Windows.Markup; |
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("WpfDesign.Designer")] |
|
||||||
[assembly: AssemblyDescription("")] |
|
||||||
[assembly: AssemblyConfiguration("")] |
|
||||||
[assembly: AssemblyTrademark("")] |
|
||||||
[assembly: AssemblyCulture("")] |
|
||||||
[assembly: CLSCompliant(true)] |
|
||||||
|
|
||||||
//In order to begin building localizable applications, set
|
|
||||||
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
|
|
||||||
//inside a <PropertyGroup>. For example, if you are using US english
|
|
||||||
//in your source files, set the <UICulture> to en-US. Then uncomment
|
|
||||||
//the NeutralResourceLanguage attribute below. Update the "en-US" in
|
|
||||||
//the line below to match the UICulture setting in the project file.
|
|
||||||
|
|
||||||
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
|
||||||
|
|
||||||
|
|
||||||
[assembly: ThemeInfo( |
|
||||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
|
||||||
//(used if a resource is not found in the page,
|
|
||||||
// or application resource dictionaries)
|
|
||||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
|
||||||
//(used if a resource is not found in the page,
|
|
||||||
// app, or any theme specific resource dictionaries)
|
|
||||||
)] |
|
||||||
|
|
||||||
[assembly: XmlnsPrefix("http://sharpdevelop.net", "sd")] |
|
||||||
|
|
||||||
[assembly: XmlnsDefinition("http://sharpdevelop.net", "ICSharpCode.WpfDesign.Designer")] |
|
||||||
[assembly: XmlnsDefinition("http://sharpdevelop.net", "ICSharpCode.WpfDesign.Designer.Controls")] |
|
||||||
[assembly: XmlnsDefinition("http://sharpdevelop.net", "ICSharpCode.WpfDesign.Designer.PropertyGrid")] |
|
||||||
[assembly: XmlnsDefinition("http://sharpdevelop.net", "ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors")] |
|
||||||
|
|
||||||
@ -1,298 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
//#define DEBUG_ADORNERLAYER
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// A control that displays adorner panels.
|
|
||||||
/// </summary>
|
|
||||||
sealed class AdornerLayer : Panel |
|
||||||
{ |
|
||||||
#region AdornerPanelCollection
|
|
||||||
internal sealed class AdornerPanelCollection : ICollection<AdornerPanel> |
|
||||||
{ |
|
||||||
readonly AdornerLayer _layer; |
|
||||||
|
|
||||||
public AdornerPanelCollection(AdornerLayer layer) |
|
||||||
{ |
|
||||||
this._layer = layer; |
|
||||||
} |
|
||||||
|
|
||||||
public int Count { |
|
||||||
get { return _layer.Children.Count; } |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsReadOnly { |
|
||||||
get { return false; } |
|
||||||
} |
|
||||||
|
|
||||||
public void Add(AdornerPanel item) |
|
||||||
{ |
|
||||||
if (item == null) |
|
||||||
throw new ArgumentNullException("item"); |
|
||||||
|
|
||||||
_layer.AddAdorner(item); |
|
||||||
} |
|
||||||
|
|
||||||
public void Clear() |
|
||||||
{ |
|
||||||
_layer.ClearAdorners(); |
|
||||||
} |
|
||||||
|
|
||||||
public bool Contains(AdornerPanel item) |
|
||||||
{ |
|
||||||
if (item == null) |
|
||||||
throw new ArgumentNullException("item"); |
|
||||||
|
|
||||||
return VisualTreeHelper.GetParent(item) == _layer; |
|
||||||
} |
|
||||||
|
|
||||||
public void CopyTo(AdornerPanel[] array, int arrayIndex) |
|
||||||
{ |
|
||||||
foreach (AdornerPanel panel in this) |
|
||||||
array[arrayIndex++] = panel; |
|
||||||
} |
|
||||||
|
|
||||||
public bool Remove(AdornerPanel item) |
|
||||||
{ |
|
||||||
if (item == null) |
|
||||||
throw new ArgumentNullException("item"); |
|
||||||
|
|
||||||
return _layer.RemoveAdorner(item); |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerator<AdornerPanel> GetEnumerator() |
|
||||||
{ |
|
||||||
foreach (AdornerPanel panel in _layer.Children) { |
|
||||||
yield return panel; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() |
|
||||||
{ |
|
||||||
return this.GetEnumerator(); |
|
||||||
} |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
AdornerPanelCollection _adorners; |
|
||||||
readonly UIElement _designPanel; |
|
||||||
|
|
||||||
#if DEBUG_ADORNERLAYER
|
|
||||||
int _totalAdornerCount; |
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
internal AdornerLayer(UIElement designPanel) |
|
||||||
{ |
|
||||||
this._designPanel = designPanel; |
|
||||||
|
|
||||||
this.LayoutUpdated += OnLayoutUpdated; |
|
||||||
|
|
||||||
_adorners = new AdornerPanelCollection(this); |
|
||||||
} |
|
||||||
|
|
||||||
void OnLayoutUpdated(object sender, EventArgs e) |
|
||||||
{ |
|
||||||
UpdateAllAdorners(false); |
|
||||||
#if DEBUG_ADORNERLAYER
|
|
||||||
Debug.WriteLine("Adorner LayoutUpdated. AdornedElements=" + _dict.Count + |
|
||||||
", visible adorners=" + VisualChildrenCount + ", total adorners=" + (_totalAdornerCount)); |
|
||||||
#endif
|
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) |
|
||||||
{ |
|
||||||
base.OnRenderSizeChanged(sizeInfo); |
|
||||||
UpdateAllAdorners(true); |
|
||||||
} |
|
||||||
|
|
||||||
internal AdornerPanelCollection Adorners { |
|
||||||
get { |
|
||||||
return _adorners; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class AdornerInfo |
|
||||||
{ |
|
||||||
internal readonly List<AdornerPanel> adorners = new List<AdornerPanel>(); |
|
||||||
internal bool isVisible; |
|
||||||
internal Rect position; |
|
||||||
} |
|
||||||
|
|
||||||
// adorned element => AdornerInfo
|
|
||||||
Dictionary<UIElement, AdornerInfo> _dict = new Dictionary<UIElement, AdornerInfo>(); |
|
||||||
|
|
||||||
void ClearAdorners() |
|
||||||
{ |
|
||||||
if (_dict.Count == 0) |
|
||||||
return; // already empty
|
|
||||||
|
|
||||||
this.Children.Clear(); |
|
||||||
_dict = new Dictionary<UIElement, AdornerInfo>(); |
|
||||||
|
|
||||||
#if DEBUG_ADORNERLAYER
|
|
||||||
_totalAdornerCount = 0; |
|
||||||
Debug.WriteLine("AdornerLayer cleared."); |
|
||||||
#endif
|
|
||||||
} |
|
||||||
|
|
||||||
AdornerInfo GetOrCreateAdornerInfo(UIElement adornedElement) |
|
||||||
{ |
|
||||||
AdornerInfo info; |
|
||||||
if (!_dict.TryGetValue(adornedElement, out info)) { |
|
||||||
info = _dict[adornedElement] = new AdornerInfo(); |
|
||||||
info.isVisible = adornedElement.IsDescendantOf(_designPanel); |
|
||||||
} |
|
||||||
return info; |
|
||||||
} |
|
||||||
|
|
||||||
AdornerInfo GetExistingAdornerInfo(UIElement adornedElement) |
|
||||||
{ |
|
||||||
AdornerInfo info; |
|
||||||
_dict.TryGetValue(adornedElement, out info); |
|
||||||
return info; |
|
||||||
} |
|
||||||
|
|
||||||
void AddAdorner(AdornerPanel adornerPanel) |
|
||||||
{ |
|
||||||
if (adornerPanel.AdornedElement == null) |
|
||||||
throw new DesignerException("adornerPanel.AdornedElement must be set"); |
|
||||||
|
|
||||||
AdornerInfo info = GetOrCreateAdornerInfo(adornerPanel.AdornedElement); |
|
||||||
info.adorners.Add(adornerPanel); |
|
||||||
|
|
||||||
if (info.isVisible) { |
|
||||||
AddAdornerToChildren(adornerPanel); |
|
||||||
} |
|
||||||
|
|
||||||
#if DEBUG_ADORNERLAYER
|
|
||||||
Debug.WriteLine("Adorner added. AdornedElements=" + _dict.Count + |
|
||||||
", visible adorners=" + VisualChildrenCount + ", total adorners=" + (++_totalAdornerCount)); |
|
||||||
#endif
|
|
||||||
} |
|
||||||
|
|
||||||
void AddAdornerToChildren(AdornerPanel adornerPanel) |
|
||||||
{ |
|
||||||
UIElementCollection children = this.Children; |
|
||||||
int i = 0; |
|
||||||
for (i = 0; i < children.Count; i++) { |
|
||||||
AdornerPanel p = (AdornerPanel)children[i]; |
|
||||||
if (p.Order.CompareTo(adornerPanel.Order) > 0) { |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
children.Insert(i, adornerPanel); |
|
||||||
} |
|
||||||
|
|
||||||
protected override Size MeasureOverride(Size availableSize) |
|
||||||
{ |
|
||||||
Size infiniteSize = new Size(double.PositiveInfinity, double.PositiveInfinity); |
|
||||||
foreach (AdornerPanel adorner in this.Children) { |
|
||||||
adorner.Measure(infiniteSize); |
|
||||||
} |
|
||||||
return new Size(0, 0); |
|
||||||
} |
|
||||||
|
|
||||||
protected override Size ArrangeOverride(Size finalSize) |
|
||||||
{ |
|
||||||
foreach (AdornerPanel adorner in this.Children) { |
|
||||||
adorner.Arrange(new Rect(new Point(0, 0), adorner.DesiredSize)); |
|
||||||
if (adorner.AdornedElement.IsDescendantOf(_designPanel)) { |
|
||||||
adorner.RenderTransform = (Transform)adorner.AdornedElement.TransformToAncestor(_designPanel); |
|
||||||
} |
|
||||||
} |
|
||||||
return finalSize; |
|
||||||
} |
|
||||||
|
|
||||||
bool RemoveAdorner(AdornerPanel adornerPanel) |
|
||||||
{ |
|
||||||
if (adornerPanel.AdornedElement == null) |
|
||||||
return false; |
|
||||||
|
|
||||||
AdornerInfo info = GetExistingAdornerInfo(adornerPanel.AdornedElement); |
|
||||||
if (info == null) |
|
||||||
return false; |
|
||||||
|
|
||||||
if (info.adorners.Remove(adornerPanel)) { |
|
||||||
if (info.isVisible) { |
|
||||||
this.Children.Remove(adornerPanel); |
|
||||||
} |
|
||||||
|
|
||||||
if (info.adorners.Count == 0) { |
|
||||||
_dict.Remove(adornerPanel.AdornedElement); |
|
||||||
} |
|
||||||
|
|
||||||
#if DEBUG_ADORNERLAYER
|
|
||||||
Debug.WriteLine("Adorner removed. AdornedElements=" + _dict.Count + |
|
||||||
", visible adorners=" + VisualChildrenCount + ", total adorners=" + (--_totalAdornerCount)); |
|
||||||
#endif
|
|
||||||
|
|
||||||
return true; |
|
||||||
} else { |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void UpdateAdornersForElement(UIElement element, bool forceInvalidate) |
|
||||||
{ |
|
||||||
AdornerInfo info = GetExistingAdornerInfo(element); |
|
||||||
if (info != null) { |
|
||||||
UpdateAdornersForElement(element, info, forceInvalidate); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
Rect GetPositionCache(UIElement element) |
|
||||||
{ |
|
||||||
Transform t = (Transform)element.TransformToAncestor(_designPanel); |
|
||||||
return new Rect(new Point(t.Value.OffsetX, t.Value.OffsetY), element.RenderSize); |
|
||||||
} |
|
||||||
|
|
||||||
void UpdateAdornersForElement(UIElement element, AdornerInfo info, bool forceInvalidate) |
|
||||||
{ |
|
||||||
if (element.IsDescendantOf(_designPanel)) { |
|
||||||
if (!info.isVisible) { |
|
||||||
info.isVisible = true; |
|
||||||
// make adorners visible:
|
|
||||||
info.adorners.ForEach(AddAdornerToChildren); |
|
||||||
} |
|
||||||
Rect c = GetPositionCache(element); |
|
||||||
if (forceInvalidate || !info.position.Equals(c)) { |
|
||||||
info.position = c; |
|
||||||
foreach (AdornerPanel p in info.adorners) { |
|
||||||
p.InvalidateMeasure(); |
|
||||||
} |
|
||||||
this.InvalidateArrange(); |
|
||||||
} |
|
||||||
} else { |
|
||||||
if (info.isVisible) { |
|
||||||
info.isVisible = false; |
|
||||||
// make adorners invisible:
|
|
||||||
info.adorners.ForEach(this.Children.Remove); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void UpdateAllAdorners(bool forceInvalidate) |
|
||||||
{ |
|
||||||
foreach (KeyValuePair<UIElement, AdornerInfo> pair in _dict) { |
|
||||||
UpdateAdornersForElement(pair.Key, pair.Value, forceInvalidate); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,32 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// A thumb where the look can depend on the IsPrimarySelection property.
|
|
||||||
/// Used by UIElementSelectionRectangle.
|
|
||||||
/// </summary>
|
|
||||||
public class ContainerDragHandle : Control |
|
||||||
{ |
|
||||||
static ContainerDragHandle() |
|
||||||
{ |
|
||||||
//This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
|
|
||||||
//This style is defined in themes\generic.xaml
|
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ContainerDragHandle), new FrameworkPropertyMetadata(typeof(ContainerDragHandle))); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,416 +0,0 @@ |
|||||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:Controls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls"> |
|
||||||
<!-- |
|
||||||
This file contains the default styles used by the Controls in ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
--> |
|
||||||
|
|
||||||
<ResourceDictionary.MergedDictionaries> |
|
||||||
<ResourceDictionary Source="NumericUpDown.xaml" /> |
|
||||||
</ResourceDictionary.MergedDictionaries> |
|
||||||
|
|
||||||
<Style x:Key="ZoomButtonStyle" |
|
||||||
TargetType="RepeatButton"> |
|
||||||
<Setter Property="Delay" |
|
||||||
Value="0" /> |
|
||||||
<Setter Property="Focusable" |
|
||||||
Value="False" /> |
|
||||||
<Setter Property="Opacity" |
|
||||||
Value="0.5" /> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="RepeatButton"> |
|
||||||
<ContentPresenter Margin="5"/> |
|
||||||
<ControlTemplate.Triggers> |
|
||||||
<Trigger Property="IsMouseOver" |
|
||||||
Value="True"> |
|
||||||
<Setter Property="Opacity" |
|
||||||
Value="1" /> |
|
||||||
</Trigger> |
|
||||||
</ControlTemplate.Triggers> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Controls:ZoomControl}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:ZoomControl}"> |
|
||||||
<Border Background="{TemplateBinding Background}" |
|
||||||
BorderBrush="{TemplateBinding BorderBrush}" |
|
||||||
BorderThickness="{TemplateBinding BorderThickness}"> |
|
||||||
<Grid> |
|
||||||
<ScrollViewer x:Name="scrollViewer" |
|
||||||
HorizontalScrollBarVisibility="Visible" |
|
||||||
VerticalScrollBarVisibility="Visible"> |
|
||||||
<Border x:Name="container" |
|
||||||
VerticalAlignment="Center" |
|
||||||
HorizontalAlignment="Center"> |
|
||||||
<ContentPresenter /> |
|
||||||
</Border> |
|
||||||
</ScrollViewer> |
|
||||||
<StackPanel Orientation="Vertical" |
|
||||||
HorizontalAlignment="Left" |
|
||||||
VerticalAlignment="Bottom" |
|
||||||
Margin="3 0 0 20" |
|
||||||
Background="#3000"> |
|
||||||
<RepeatButton x:Name="uxPlus" |
|
||||||
Style="{StaticResource ZoomButtonStyle}"> |
|
||||||
<Image Source="../Images/ZoomIn.png" |
|
||||||
Stretch="None"/> |
|
||||||
</RepeatButton> |
|
||||||
<RepeatButton x:Name="uxMinus" |
|
||||||
Style="{StaticResource ZoomButtonStyle}"> |
|
||||||
<Image Source="../Images/ZoomOut.png" |
|
||||||
Stretch="None" /> |
|
||||||
</RepeatButton> |
|
||||||
<RepeatButton x:Name="uxReset" |
|
||||||
Style="{StaticResource ZoomButtonStyle}"> |
|
||||||
<Border Background="#5000" |
|
||||||
Width="16" |
|
||||||
Height="16"> |
|
||||||
<TextBlock Foreground="White" |
|
||||||
HorizontalAlignment="Center" |
|
||||||
VerticalAlignment="Center">1</TextBlock> |
|
||||||
</Border> |
|
||||||
</RepeatButton> |
|
||||||
</StackPanel> |
|
||||||
</Grid> |
|
||||||
</Border> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Controls:PanelMoveAdorner}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:PanelMoveAdorner}"> |
|
||||||
<Border BorderThickness="4" |
|
||||||
Margin="-2" |
|
||||||
BorderBrush="Transparent" |
|
||||||
Cursor="SizeAll" /> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Controls:EnumButton}" |
|
||||||
BasedOn="{StaticResource {x:Type ToggleButton}}"> |
|
||||||
<Setter Property="Margin" |
|
||||||
Value="3 3 0 3" /> |
|
||||||
<Setter Property="MinWidth" |
|
||||||
Value="50" /> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Controls:ResizeThumb}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:ResizeThumb}"> |
|
||||||
<Rectangle Name="thumbRectangle" |
|
||||||
Width="7" |
|
||||||
Height="7" |
|
||||||
SnapsToDevicePixels="True" |
|
||||||
Stroke="Black" |
|
||||||
Fill="White" |
|
||||||
RadiusX="1.414" |
|
||||||
RadiusY="1.414" /> |
|
||||||
<ControlTemplate.Triggers> |
|
||||||
<Trigger Property="IsPrimarySelection" |
|
||||||
Value="False"> |
|
||||||
<Setter TargetName="thumbRectangle" |
|
||||||
Property="Stroke" |
|
||||||
Value="White" /> |
|
||||||
<Setter TargetName="thumbRectangle" |
|
||||||
Property="Fill" |
|
||||||
Value="Black" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="IsEnabled" |
|
||||||
Value="False"> |
|
||||||
<Setter TargetName="thumbRectangle" |
|
||||||
Property="Fill" |
|
||||||
Value="Gray" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="ResizeThumbVisible" |
|
||||||
Value="False"> |
|
||||||
<Setter TargetName="thumbRectangle" |
|
||||||
Property="Visibility" |
|
||||||
Value="Hidden" /> |
|
||||||
</Trigger> |
|
||||||
</ControlTemplate.Triggers> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Controls:SelectionFrame}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:SelectionFrame}"> |
|
||||||
<Rectangle Fill="#519ABFE5" |
|
||||||
Stroke="#FF7A8787" |
|
||||||
StrokeThickness="1" /> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Controls:ContainerDragHandle}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:ContainerDragHandle}"> |
|
||||||
<Canvas Height="13" |
|
||||||
Width="13" |
|
||||||
Name="Canvas" |
|
||||||
SnapsToDevicePixels="True"> |
|
||||||
<Rectangle Height="13" |
|
||||||
Width="13" |
|
||||||
RadiusX="2" |
|
||||||
RadiusY="2" |
|
||||||
Fill="#889ABFE5" |
|
||||||
Name="BorderRectangle" |
|
||||||
Stroke="#FF7A8FB5" |
|
||||||
StrokeThickness="1" /> |
|
||||||
<Path Fill="#FF748EAA" |
|
||||||
Canvas.Left="1" |
|
||||||
Canvas.Top="1"> |
|
||||||
<Path.Data> |
|
||||||
<GeometryGroup> |
|
||||||
<PathGeometry Figures="M5.5,0L3,3L8,3 M11,5.5L8,3L8,8 M5.5,11L3,8L8,8 M0,5.5L3,3L3,8" /> |
|
||||||
<RectangleGeometry Rect="3,5,5,1" /> |
|
||||||
<RectangleGeometry Rect="5,3,1,5" /> |
|
||||||
<RectangleGeometry Rect="5,5,1,1" /> |
|
||||||
</GeometryGroup> |
|
||||||
</Path.Data> |
|
||||||
</Path> |
|
||||||
</Canvas> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Controls:WindowClone}"> |
|
||||||
<Setter Property="Width" |
|
||||||
Value="640" /> |
|
||||||
<Setter Property="Height" |
|
||||||
Value="480" /> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:WindowClone}"> |
|
||||||
<Border Background="{DynamicResource {x:Static SystemColors.GradientActiveCaptionBrushKey}}" |
|
||||||
BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" |
|
||||||
BorderThickness="1,1,1,1" |
|
||||||
CornerRadius="5,5,5,5"> |
|
||||||
<DockPanel Margin="4,0,4,4"> |
|
||||||
<DockPanel Height="26" |
|
||||||
DockPanel.Dock="Top"> |
|
||||||
<Image Width="16" |
|
||||||
Height="16" |
|
||||||
Margin="1,0,0,0" |
|
||||||
Source="{TemplateBinding Window.Icon}" /> |
|
||||||
<Button Name="CloseButton" |
|
||||||
VerticalAlignment="Top" |
|
||||||
Width="43" |
|
||||||
Height="17" |
|
||||||
DockPanel.Dock="Right"> |
|
||||||
<Path Fill="#FFF6F2F2" |
|
||||||
Stretch="Uniform" |
|
||||||
Margin="1" |
|
||||||
Stroke="#FF808080" |
|
||||||
Data="M160,400 L176,400 192,384 208,400 224,400 200,376 224,352 208,352 192,368 176,352 160,352 184,376 z" /> |
|
||||||
</Button> |
|
||||||
<Button Name="MaximiseButton" |
|
||||||
VerticalAlignment="Top" |
|
||||||
Width="25" |
|
||||||
Height="17" |
|
||||||
DockPanel.Dock="Right" /> |
|
||||||
<Button Name="MinimizeButton" |
|
||||||
VerticalAlignment="Top" |
|
||||||
Width="25" |
|
||||||
Height="17" |
|
||||||
DockPanel.Dock="Right"> |
|
||||||
<!--<Rectangle Fill="#FFF6F2F2" RadiusX="0.5" RadiusY="0.5" Width="12" Height="5" Stroke="#FF808080" VerticalAlignment="Bottom" HorizontalAlignment="Center"/>--> |
|
||||||
</Button> |
|
||||||
<Label Margin="4,0,0,0" |
|
||||||
Content="{TemplateBinding Window.Title}" /> |
|
||||||
</DockPanel> |
|
||||||
<Border Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"> |
|
||||||
<Border BorderBrush="{TemplateBinding Border.BorderBrush}" |
|
||||||
BorderThickness="{TemplateBinding Border.BorderThickness}" |
|
||||||
Background="{TemplateBinding Panel.Background}"> |
|
||||||
<AdornerDecorator> |
|
||||||
<ContentPresenter ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" |
|
||||||
Content="{TemplateBinding ContentControl.Content}" /> |
|
||||||
</AdornerDecorator> |
|
||||||
</Border> |
|
||||||
</Border> |
|
||||||
</DockPanel> |
|
||||||
</Border> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Controls:ErrorBalloon}"> |
|
||||||
<Setter Property="WindowStyle" |
|
||||||
Value="None" /> |
|
||||||
<Setter Property="AllowsTransparency" |
|
||||||
Value="True" /> |
|
||||||
<Setter Property="SizeToContent" |
|
||||||
Value="WidthAndHeight" /> |
|
||||||
<Setter Property="ShowInTaskbar" |
|
||||||
Value="False" /> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:ErrorBalloon}"> |
|
||||||
<Grid x:Name="LayoutRoot"> |
|
||||||
<Grid.ColumnDefinitions> |
|
||||||
<ColumnDefinition Width="*" /> |
|
||||||
</Grid.ColumnDefinitions> |
|
||||||
<Rectangle RadiusX="10" |
|
||||||
RadiusY="10" |
|
||||||
Margin="12,36,4,4"> |
|
||||||
<Rectangle.Fill> |
|
||||||
<SolidColorBrush Color="#41626262" /> |
|
||||||
</Rectangle.Fill> |
|
||||||
</Rectangle> |
|
||||||
<Border Margin="8,32,8,8" |
|
||||||
Background="{DynamicResource {x:Static SystemColors.InfoBrushKey}}" |
|
||||||
BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" |
|
||||||
BorderThickness="1,1,1,1" |
|
||||||
CornerRadius="10,10,10,10" |
|
||||||
Padding="10,10,10,10"> |
|
||||||
<Border BorderBrush="{TemplateBinding Border.BorderBrush}" |
|
||||||
BorderThickness="{TemplateBinding Border.BorderThickness}" |
|
||||||
Background="{TemplateBinding Panel.Background}"> |
|
||||||
<AdornerDecorator> |
|
||||||
<ContentPresenter ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" |
|
||||||
Content="{TemplateBinding ContentControl.Content}" /> |
|
||||||
</AdornerDecorator> |
|
||||||
</Border> |
|
||||||
</Border> |
|
||||||
<Path Fill="{DynamicResource {x:Static SystemColors.InfoBrushKey}}" |
|
||||||
Stretch="Fill" |
|
||||||
HorizontalAlignment="Left" |
|
||||||
Margin="34.75,9.25,0,0" |
|
||||||
VerticalAlignment="Top" |
|
||||||
Width="15.25" |
|
||||||
Height="24.5" |
|
||||||
Data="M34.75,33.75 L40.5,9.25 50,33.5 z" /> |
|
||||||
<Path Stretch="Fill" |
|
||||||
Stroke="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" |
|
||||||
HorizontalAlignment="Left" |
|
||||||
Margin="34.5,9.25,0,0" |
|
||||||
VerticalAlignment="Top" |
|
||||||
Width="16" |
|
||||||
Height="24" |
|
||||||
Data="M35,32.75 L40.5,9.25 50,32.75" /> |
|
||||||
</Grid> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Controls:GridRailAdorner}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:GridRailAdorner}"> |
|
||||||
<Rectangle Fill="#302020ff" /> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Controls:GridRowSplitterAdorner}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:GridRowSplitterAdorner}"> |
|
||||||
<Grid Height="{x:Static Controls:GridRailAdorner.SplitterWidth}"> |
|
||||||
<Grid.ColumnDefinitions> |
|
||||||
<ColumnDefinition Width="10" /> |
|
||||||
<!-- 10=RailSize --> |
|
||||||
<ColumnDefinition Width="*" /> |
|
||||||
</Grid.ColumnDefinitions> |
|
||||||
<!-- put a transparent rectangle in the rail so the user does not have to hit the small railHandle --> |
|
||||||
<Rectangle Fill="Transparent" /> |
|
||||||
<Path Name="railHandle" |
|
||||||
Fill="#FFE6E6FF" |
|
||||||
Stretch="Fill" |
|
||||||
Stroke="#FF584FFF" |
|
||||||
Data="M0,0 L0,1 1,0.5 z" /> |
|
||||||
<Path Name="line" |
|
||||||
Stretch="Fill" |
|
||||||
Stroke="#FF584FFF" |
|
||||||
Grid.Column="2" |
|
||||||
Margin="-1 0 0 0" |
|
||||||
Data="M0,0.5 L1,0.5" /> |
|
||||||
</Grid> |
|
||||||
<ControlTemplate.Triggers> |
|
||||||
<Trigger Property="IsMouseOver" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="railHandle" |
|
||||||
Property="Fill" |
|
||||||
Value="#FFFFB74F" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="IsPreview" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="railHandle" |
|
||||||
Property="Stroke" |
|
||||||
Value="#D0FFB74F" /> |
|
||||||
<Setter TargetName="line" |
|
||||||
Property="Stroke" |
|
||||||
Value="#D0FFB74F" /> |
|
||||||
</Trigger> |
|
||||||
</ControlTemplate.Triggers> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Controls:GridColumnSplitterAdorner}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:GridColumnSplitterAdorner}"> |
|
||||||
<Grid Width="{x:Static Controls:GridRailAdorner.SplitterWidth}"> |
|
||||||
<Grid.RowDefinitions> |
|
||||||
<RowDefinition Height="10" /> |
|
||||||
<!-- 10=RailSize --> |
|
||||||
<RowDefinition Height="*" /> |
|
||||||
</Grid.RowDefinitions> |
|
||||||
<!-- put a transparent rectangle in the rail so the user does not have to hit the small railHandle --> |
|
||||||
<Rectangle Fill="Transparent" /> |
|
||||||
<Path Name="railHandle" |
|
||||||
Fill="#FFE6E6FF" |
|
||||||
Stretch="Fill" |
|
||||||
Stroke="#FF584FFF" |
|
||||||
Data="M0,0 L1,0 0.5,1 z" /> |
|
||||||
<Path Name="line" |
|
||||||
Stretch="Fill" |
|
||||||
Stroke="#FF584FFF" |
|
||||||
Grid.Row="2" |
|
||||||
Margin="0 -1 0 0" |
|
||||||
Data="M0.5,0 L0.5,1" /> |
|
||||||
</Grid> |
|
||||||
<ControlTemplate.Triggers> |
|
||||||
<Trigger Property="IsMouseOver" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="railHandle" |
|
||||||
Property="Fill" |
|
||||||
Value="#FFFFB74F" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="IsPreview" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="railHandle" |
|
||||||
Property="Stroke" |
|
||||||
Value="#D0FFB74F" /> |
|
||||||
<Setter TargetName="line" |
|
||||||
Property="Stroke" |
|
||||||
Value="#D0FFB74F" /> |
|
||||||
</Trigger> |
|
||||||
</ControlTemplate.Triggers> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
</ResourceDictionary> |
|
||||||
@ -1,111 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Diagnostics; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
public delegate void DragHandler(DragListener drag); |
|
||||||
|
|
||||||
public class DragListener |
|
||||||
{ |
|
||||||
static DragListener() |
|
||||||
{ |
|
||||||
InputManager.Current.PostProcessInput += new ProcessInputEventHandler(PostProcessInput); |
|
||||||
} |
|
||||||
|
|
||||||
public DragListener(IInputElement target) |
|
||||||
{ |
|
||||||
Target = target; |
|
||||||
|
|
||||||
Target.PreviewMouseLeftButtonDown += Target_MouseDown; |
|
||||||
Target.PreviewMouseMove += Target_MouseMove; |
|
||||||
Target.PreviewMouseLeftButtonUp += Target_MouseUp; |
|
||||||
} |
|
||||||
|
|
||||||
static DragListener CurrentListener; |
|
||||||
|
|
||||||
static void PostProcessInput(object sender, ProcessInputEventArgs e) |
|
||||||
{ |
|
||||||
if (CurrentListener != null) { |
|
||||||
var a = e.StagingItem.Input as KeyEventArgs; |
|
||||||
if (a != null && a.Key == Key.Escape) { |
|
||||||
Mouse.Capture(null); |
|
||||||
CurrentListener.IsDown = false; |
|
||||||
CurrentListener.IsCanceled = true; |
|
||||||
CurrentListener.Complete(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void Target_MouseDown(object sender, MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
StartPoint = Mouse.GetPosition(null); |
|
||||||
CurrentPoint = StartPoint; |
|
||||||
DeltaDelta = new Vector(); |
|
||||||
IsDown = true; |
|
||||||
IsCanceled = false; |
|
||||||
} |
|
||||||
|
|
||||||
void Target_MouseMove(object sender, MouseEventArgs e) |
|
||||||
{ |
|
||||||
if (IsDown) { |
|
||||||
DeltaDelta = e.GetPosition(null) - CurrentPoint; |
|
||||||
CurrentPoint += DeltaDelta; |
|
||||||
|
|
||||||
if (!IsActive) { |
|
||||||
if (Math.Abs(Delta.X) >= SystemParameters.MinimumHorizontalDragDistance || |
|
||||||
Math.Abs(Delta.Y) >= SystemParameters.MinimumVerticalDragDistance) { |
|
||||||
IsActive = true; |
|
||||||
CurrentListener = this; |
|
||||||
|
|
||||||
if (Started != null) { |
|
||||||
Started(this); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (IsActive && Changed != null) { |
|
||||||
Changed(this); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void Target_MouseUp(object sender, MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
IsDown = false; |
|
||||||
if (IsActive) { |
|
||||||
Complete(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void Complete() |
|
||||||
{ |
|
||||||
IsActive = false; |
|
||||||
CurrentListener = null; |
|
||||||
|
|
||||||
if (Completed != null) { |
|
||||||
Completed(this); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public event DragHandler Started; |
|
||||||
public event DragHandler Changed; |
|
||||||
public event DragHandler Completed; |
|
||||||
|
|
||||||
public IInputElement Target { get; private set; } |
|
||||||
public Point StartPoint { get; private set; } |
|
||||||
public Point CurrentPoint { get; private set; } |
|
||||||
public Vector DeltaDelta { get; private set; } |
|
||||||
public bool IsActive { get; private set; } |
|
||||||
public bool IsDown { get; private set; } |
|
||||||
public bool IsCanceled { get; private set; } |
|
||||||
|
|
||||||
public Vector Delta { |
|
||||||
get { return CurrentPoint - StartPoint; } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,33 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <author name="Daniel Grunwald"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Shapes; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// A button with a drop-down arrow.
|
|
||||||
/// </summary>
|
|
||||||
public class DropDownButton : Button |
|
||||||
{ |
|
||||||
static readonly Geometry triangle = (Geometry)new GeometryConverter().ConvertFromInvariantString("M0,0 L1,0 0.5,1 z"); |
|
||||||
|
|
||||||
public DropDownButton() |
|
||||||
{ |
|
||||||
Content = new Path { |
|
||||||
Fill = Brushes.Black, |
|
||||||
Data = triangle, |
|
||||||
Width = 7, |
|
||||||
Height = 3.5, |
|
||||||
Stretch = Stretch.Fill |
|
||||||
}; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,31 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
public class EnterTextBox : TextBox |
|
||||||
{ |
|
||||||
protected override void OnKeyDown(KeyEventArgs e) |
|
||||||
{ |
|
||||||
if (e.Key == Key.Enter) { |
|
||||||
var b = BindingOperations.GetBindingExpressionBase(this, TextProperty); |
|
||||||
if (b != null) { |
|
||||||
b.UpdateSource(); |
|
||||||
} |
|
||||||
SelectAll(); |
|
||||||
} |
|
||||||
else if (e.Key == Key.Escape) { |
|
||||||
var b = BindingOperations.GetBindingExpressionBase(this, TextProperty); |
|
||||||
if (b != null) { |
|
||||||
b.UpdateTarget(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,7 +0,0 @@ |
|||||||
<UserControl |
|
||||||
x:Class="ICSharpCode.WpfDesign.Designer.Controls.EnumBar" |
|
||||||
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
|
||||||
<StackPanel x:Name="uxPanel" |
|
||||||
Orientation="Horizontal" /> |
|
||||||
</UserControl> |
|
||||||
@ -1,112 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
public partial class EnumBar |
|
||||||
{ |
|
||||||
public EnumBar() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
} |
|
||||||
|
|
||||||
Type currentEnumType; |
|
||||||
|
|
||||||
public static readonly DependencyProperty ValueProperty = |
|
||||||
DependencyProperty.Register("Value", typeof(object), typeof(EnumBar), |
|
||||||
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); |
|
||||||
|
|
||||||
public object Value { |
|
||||||
get { return (object)GetValue(ValueProperty); } |
|
||||||
set { SetValue(ValueProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty ContainerProperty = |
|
||||||
DependencyProperty.Register("Container", typeof(Panel), typeof(EnumBar)); |
|
||||||
|
|
||||||
public Panel Container { |
|
||||||
get { return (Panel)GetValue(ContainerProperty); } |
|
||||||
set { SetValue(ContainerProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty ButtonStyleProperty = |
|
||||||
DependencyProperty.Register("ButtonStyle", typeof(Style), typeof(EnumBar)); |
|
||||||
|
|
||||||
public Style ButtonStyle { |
|
||||||
get { return (Style)GetValue(ButtonStyleProperty); } |
|
||||||
set { SetValue(ButtonStyleProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
base.OnPropertyChanged(e); |
|
||||||
|
|
||||||
if (e.Property == ValueProperty) { |
|
||||||
|
|
||||||
var type = e.NewValue.GetType(); |
|
||||||
|
|
||||||
if (currentEnumType != type) { |
|
||||||
currentEnumType = type; |
|
||||||
uxPanel.Children.Clear(); |
|
||||||
foreach (var v in Enum.GetValues(type)) { |
|
||||||
var b = new EnumButton(); |
|
||||||
b.Value = v; |
|
||||||
b.Content = Enum.GetName(type, v); |
|
||||||
b.SetBinding(StyleProperty, new Binding("ButtonStyle") { Source = this }); |
|
||||||
b.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(button_PreviewMouseLeftButtonDown); |
|
||||||
uxPanel.Children.Add(b); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
UpdateButtons(); |
|
||||||
UpdateContainer(); |
|
||||||
|
|
||||||
} else if (e.Property == ContainerProperty) { |
|
||||||
UpdateContainer(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void UpdateButtons() |
|
||||||
{ |
|
||||||
foreach (EnumButton c in uxPanel.Children) { |
|
||||||
if (c.Value.Equals(Value)) { |
|
||||||
c.IsChecked = true; |
|
||||||
} |
|
||||||
else { |
|
||||||
c.IsChecked = false; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void UpdateContainer() |
|
||||||
{ |
|
||||||
if (Container != null) { |
|
||||||
for (int i = 0; i < uxPanel.Children.Count; i++) { |
|
||||||
var c = uxPanel.Children[i] as EnumButton; |
|
||||||
if (c.IsChecked.Value) |
|
||||||
Container.Children[i].Visibility = Visibility.Visible; |
|
||||||
else |
|
||||||
Container.Children[i].Visibility = Visibility.Collapsed; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
Value = (sender as EnumButton).Value; |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,26 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
using System.Windows; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
public class EnumButton : ToggleButton |
|
||||||
{ |
|
||||||
static EnumButton() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(EnumButton), |
|
||||||
new FrameworkPropertyMetadata(typeof(EnumButton))); |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty ValueProperty = |
|
||||||
DependencyProperty.Register("Value", typeof(object), typeof(EnumButton)); |
|
||||||
|
|
||||||
public object Value { |
|
||||||
get { return (object)GetValue(ValueProperty); } |
|
||||||
set { SetValue(ValueProperty, value); } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,23 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Windows; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// An ErrorBalloon window.
|
|
||||||
/// </summary>
|
|
||||||
public class ErrorBalloon : Window |
|
||||||
{ |
|
||||||
static ErrorBalloon() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ErrorBalloon), new FrameworkPropertyMetadata(typeof(ErrorBalloon))); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,121 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Threading; |
|
||||||
using System.Windows.Media.Animation; |
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Services; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Gray out everything except a specific area.
|
|
||||||
/// </summary>
|
|
||||||
sealed class GrayOutDesignerExceptActiveArea : FrameworkElement |
|
||||||
{ |
|
||||||
Geometry designSurfaceRectangle; |
|
||||||
Geometry activeAreaGeometry; |
|
||||||
Geometry combinedGeometry; |
|
||||||
Brush grayOutBrush; |
|
||||||
AdornerPanel adornerPanel; |
|
||||||
IDesignPanel designPanel; |
|
||||||
const double MaxOpacity = 0.3; |
|
||||||
|
|
||||||
public GrayOutDesignerExceptActiveArea() |
|
||||||
{ |
|
||||||
this.GrayOutBrush = new SolidColorBrush(SystemColors.GrayTextColor); |
|
||||||
this.GrayOutBrush.Opacity = MaxOpacity; |
|
||||||
this.IsHitTestVisible = false; |
|
||||||
} |
|
||||||
|
|
||||||
public Brush GrayOutBrush { |
|
||||||
get { return grayOutBrush; } |
|
||||||
set { grayOutBrush = value; } |
|
||||||
} |
|
||||||
|
|
||||||
public Geometry ActiveAreaGeometry { |
|
||||||
get { return activeAreaGeometry; } |
|
||||||
set { |
|
||||||
activeAreaGeometry = value; |
|
||||||
combinedGeometry = new CombinedGeometry(GeometryCombineMode.Exclude, designSurfaceRectangle, activeAreaGeometry); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnRender(DrawingContext drawingContext) |
|
||||||
{ |
|
||||||
drawingContext.DrawGeometry(grayOutBrush, null, combinedGeometry); |
|
||||||
} |
|
||||||
|
|
||||||
Rect currentAnimateActiveAreaRectToTarget; |
|
||||||
|
|
||||||
internal void AnimateActiveAreaRectTo(Rect newRect) |
|
||||||
{ |
|
||||||
if (newRect.Equals(currentAnimateActiveAreaRectToTarget)) |
|
||||||
return; |
|
||||||
activeAreaGeometry.BeginAnimation( |
|
||||||
RectangleGeometry.RectProperty, |
|
||||||
new RectAnimation(newRect, new Duration(new TimeSpan(0,0,0,0,100))), |
|
||||||
HandoffBehavior.SnapshotAndReplace); |
|
||||||
currentAnimateActiveAreaRectToTarget = newRect; |
|
||||||
} |
|
||||||
|
|
||||||
internal static void Start(ref GrayOutDesignerExceptActiveArea grayOut, ServiceContainer services, UIElement activeContainer) |
|
||||||
{ |
|
||||||
Debug.Assert(activeContainer != null); |
|
||||||
Start(ref grayOut, services, activeContainer, new Rect(activeContainer.RenderSize)); |
|
||||||
} |
|
||||||
|
|
||||||
internal static void Start(ref GrayOutDesignerExceptActiveArea grayOut, ServiceContainer services, UIElement activeContainer, Rect activeRectInActiveContainer) |
|
||||||
{ |
|
||||||
Debug.Assert(services != null); |
|
||||||
Debug.Assert(activeContainer != null); |
|
||||||
DesignPanel designPanel = services.GetService<IDesignPanel>() as DesignPanel; |
|
||||||
OptionService optionService = services.GetService<OptionService>(); |
|
||||||
if (designPanel != null && grayOut == null && optionService != null && optionService.GrayOutDesignSurfaceExceptParentContainerWhenDragging) { |
|
||||||
grayOut = new GrayOutDesignerExceptActiveArea(); |
|
||||||
grayOut.designSurfaceRectangle = new RectangleGeometry( |
|
||||||
new Rect(new Point(0, 0), designPanel.RenderSize)); |
|
||||||
grayOut.designPanel = designPanel; |
|
||||||
grayOut.adornerPanel = new AdornerPanel(); |
|
||||||
grayOut.adornerPanel.Order = AdornerOrder.BehindForeground; |
|
||||||
grayOut.adornerPanel.SetAdornedElement(designPanel.Context.RootItem.View, null); |
|
||||||
grayOut.adornerPanel.Children.Add(grayOut); |
|
||||||
grayOut.ActiveAreaGeometry = new RectangleGeometry(activeRectInActiveContainer, 0, 0, (Transform)activeContainer.TransformToVisual(grayOut.adornerPanel.AdornedElement)); |
|
||||||
Animate(grayOut.GrayOutBrush, Brush.OpacityProperty, 0, MaxOpacity); |
|
||||||
designPanel.Adorners.Add(grayOut.adornerPanel); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static readonly TimeSpan animationTime = new TimeSpan(2000000); |
|
||||||
|
|
||||||
static void Animate(Animatable element, DependencyProperty property, double from, double to) |
|
||||||
{ |
|
||||||
element.BeginAnimation(property, new DoubleAnimation(from, to, new Duration(animationTime), FillBehavior.Stop)); |
|
||||||
} |
|
||||||
|
|
||||||
internal static void Stop(ref GrayOutDesignerExceptActiveArea grayOut) |
|
||||||
{ |
|
||||||
if (grayOut != null) { |
|
||||||
Animate(grayOut.GrayOutBrush, Brush.OpacityProperty, MaxOpacity, 0); |
|
||||||
IDesignPanel designPanel = grayOut.designPanel; |
|
||||||
AdornerPanel adornerPanelToRemove = grayOut.adornerPanel; |
|
||||||
DispatcherTimer timer = new DispatcherTimer(); |
|
||||||
timer.Interval = animationTime; |
|
||||||
timer.Tick += delegate { |
|
||||||
timer.Stop(); |
|
||||||
designPanel.Adorners.Remove(adornerPanelToRemove); |
|
||||||
}; |
|
||||||
timer.Start(); |
|
||||||
grayOut = null; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,371 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Adorner that displays the blue bar next to grids that can be used to create new rows/column.
|
|
||||||
/// </summary>
|
|
||||||
public class GridRailAdorner : Control |
|
||||||
{ |
|
||||||
static GridRailAdorner() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(GridRailAdorner), new FrameworkPropertyMetadata(typeof(GridRailAdorner))); |
|
||||||
} |
|
||||||
|
|
||||||
readonly DesignItem gridItem; |
|
||||||
readonly Grid grid; |
|
||||||
readonly AdornerPanel adornerPanel; |
|
||||||
readonly GridSplitterAdorner previewAdorner; |
|
||||||
readonly Orientation orientation; |
|
||||||
|
|
||||||
public const double RailSize = 10; |
|
||||||
public const double RailDistance = 6; |
|
||||||
public const double SplitterWidth = 10; |
|
||||||
|
|
||||||
public GridRailAdorner(DesignItem gridItem, AdornerPanel adornerPanel, Orientation orientation) |
|
||||||
{ |
|
||||||
Debug.Assert(gridItem != null); |
|
||||||
Debug.Assert(adornerPanel != null); |
|
||||||
|
|
||||||
this.gridItem = gridItem; |
|
||||||
this.grid = (Grid)gridItem.Component; |
|
||||||
this.adornerPanel = adornerPanel; |
|
||||||
this.orientation = orientation; |
|
||||||
|
|
||||||
if (orientation == Orientation.Horizontal) { |
|
||||||
this.Height = RailSize; |
|
||||||
previewAdorner = new GridColumnSplitterAdorner(gridItem, null, null); |
|
||||||
} else { // vertical
|
|
||||||
this.Width = RailSize; |
|
||||||
previewAdorner = new GridRowSplitterAdorner(gridItem, null, null); |
|
||||||
} |
|
||||||
previewAdorner.IsPreview = true; |
|
||||||
previewAdorner.IsHitTestVisible = false; |
|
||||||
} |
|
||||||
|
|
||||||
#region Handle mouse events to add a new row/column
|
|
||||||
protected override void OnMouseEnter(MouseEventArgs e) |
|
||||||
{ |
|
||||||
base.OnMouseEnter(e); |
|
||||||
adornerPanel.Children.Add(previewAdorner); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseMove(MouseEventArgs e) |
|
||||||
{ |
|
||||||
base.OnMouseMove(e); |
|
||||||
RelativePlacement rp = new RelativePlacement(); |
|
||||||
if (orientation == Orientation.Vertical) { |
|
||||||
rp.XOffset = -(RailSize + RailDistance); |
|
||||||
rp.WidthOffset = RailSize + RailDistance; |
|
||||||
rp.WidthRelativeToContentWidth = 1; |
|
||||||
rp.HeightOffset = SplitterWidth; |
|
||||||
rp.YOffset = e.GetPosition(this).Y - SplitterWidth / 2; |
|
||||||
} else { |
|
||||||
rp.YOffset = -(RailSize + RailDistance); |
|
||||||
rp.HeightOffset = RailSize + RailDistance; |
|
||||||
rp.HeightRelativeToContentHeight = 1; |
|
||||||
rp.WidthOffset = SplitterWidth; |
|
||||||
rp.XOffset = e.GetPosition(this).X - SplitterWidth / 2; |
|
||||||
} |
|
||||||
AdornerPanel.SetPlacement(previewAdorner, rp); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseLeave(MouseEventArgs e) |
|
||||||
{ |
|
||||||
base.OnMouseLeave(e); |
|
||||||
adornerPanel.Children.Remove(previewAdorner); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
base.OnMouseLeftButtonDown(e); |
|
||||||
e.Handled = true; |
|
||||||
Focus(); |
|
||||||
adornerPanel.Children.Remove(previewAdorner); |
|
||||||
if (orientation == Orientation.Vertical) { |
|
||||||
using (ChangeGroup changeGroup = gridItem.OpenGroup("Split grid row")) { |
|
||||||
DesignItemProperty rowCollection = gridItem.Properties["RowDefinitions"]; |
|
||||||
if (rowCollection.CollectionElements.Count == 0) { |
|
||||||
DesignItem firstRow = gridItem.Services.Component.RegisterComponentForDesigner(new RowDefinition()); |
|
||||||
rowCollection.CollectionElements.Add(firstRow); |
|
||||||
grid.UpdateLayout(); // let WPF assign firstRow.ActualHeight
|
|
||||||
} |
|
||||||
double insertionPosition = e.GetPosition(this).Y; |
|
||||||
for (int i = 0; i < grid.RowDefinitions.Count; i++) { |
|
||||||
RowDefinition row = grid.RowDefinitions[i]; |
|
||||||
if (row.Offset > insertionPosition) continue; |
|
||||||
if (row.Offset + row.ActualHeight < insertionPosition) continue; |
|
||||||
|
|
||||||
// split row
|
|
||||||
GridLength oldLength = (GridLength)row.GetValue(RowDefinition.HeightProperty); |
|
||||||
GridLength newLength1, newLength2; |
|
||||||
SplitLength(oldLength, insertionPosition - row.Offset, row.ActualHeight, out newLength1, out newLength2); |
|
||||||
DesignItem newRowDefinition = gridItem.Services.Component.RegisterComponentForDesigner(new RowDefinition()); |
|
||||||
rowCollection.CollectionElements.Insert(i + 1, newRowDefinition); |
|
||||||
rowCollection.CollectionElements[i].Properties[RowDefinition.HeightProperty].SetValue(newLength1); |
|
||||||
newRowDefinition.Properties[RowDefinition.HeightProperty].SetValue(newLength2); |
|
||||||
|
|
||||||
FixIndicesAfterSplit(i, Grid.RowProperty, Grid.RowSpanProperty); |
|
||||||
changeGroup.Commit(); |
|
||||||
gridItem.Services.Selection.SetSelectedComponents(new DesignItem[] { newRowDefinition }, SelectionTypes.Auto); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} else { |
|
||||||
using (ChangeGroup changeGroup = gridItem.OpenGroup("Split grid column")) { |
|
||||||
DesignItemProperty columnCollection = gridItem.Properties["ColumnDefinitions"]; |
|
||||||
if (columnCollection.CollectionElements.Count == 0) { |
|
||||||
DesignItem firstColumn = gridItem.Services.Component.RegisterComponentForDesigner(new ColumnDefinition()); |
|
||||||
columnCollection.CollectionElements.Add(firstColumn); |
|
||||||
grid.UpdateLayout(); // let WPF assign firstColumn.ActualWidth
|
|
||||||
} |
|
||||||
double insertionPosition = e.GetPosition(this).X; |
|
||||||
for (int i = 0; i < grid.ColumnDefinitions.Count; i++) { |
|
||||||
ColumnDefinition column = grid.ColumnDefinitions[i]; |
|
||||||
if (column.Offset > insertionPosition) continue; |
|
||||||
if (column.Offset + column.ActualWidth < insertionPosition) continue; |
|
||||||
|
|
||||||
// split column
|
|
||||||
GridLength oldLength = (GridLength)column.GetValue(ColumnDefinition.WidthProperty); |
|
||||||
GridLength newLength1, newLength2; |
|
||||||
SplitLength(oldLength, insertionPosition - column.Offset, column.ActualWidth, out newLength1, out newLength2); |
|
||||||
DesignItem newColumnDefinition = gridItem.Services.Component.RegisterComponentForDesigner(new ColumnDefinition()); |
|
||||||
columnCollection.CollectionElements.Insert(i + 1, newColumnDefinition); |
|
||||||
columnCollection.CollectionElements[i].Properties[ColumnDefinition.WidthProperty].SetValue(newLength1); |
|
||||||
newColumnDefinition.Properties[ColumnDefinition.WidthProperty].SetValue(newLength2); |
|
||||||
FixIndicesAfterSplit(i, Grid.ColumnProperty, Grid.ColumnSpanProperty); |
|
||||||
changeGroup.Commit(); |
|
||||||
gridItem.Services.Selection.SetSelectedComponents(new DesignItem[] { newColumnDefinition }, SelectionTypes.Auto); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void FixIndicesAfterSplit(int splitIndex, DependencyProperty idxProperty, DependencyProperty spanProperty) |
|
||||||
{ |
|
||||||
// increment ColSpan of all controls in the split column, increment Column of all controls in later columns:
|
|
||||||
foreach (DesignItem child in gridItem.Properties["Children"].CollectionElements) { |
|
||||||
int start = (int)child.Properties.GetAttachedProperty(idxProperty).ValueOnInstance; |
|
||||||
int span = (int)child.Properties.GetAttachedProperty(spanProperty).ValueOnInstance; |
|
||||||
if (start <= splitIndex && splitIndex < start + span) { |
|
||||||
child.Properties.GetAttachedProperty(spanProperty).SetValue(span + 1); |
|
||||||
} else if (start > splitIndex) { |
|
||||||
child.Properties.GetAttachedProperty(idxProperty).SetValue(start + 1); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void SplitLength(GridLength oldLength, double insertionPosition, double oldActualValue, |
|
||||||
out GridLength newLength1, out GridLength newLength2) |
|
||||||
{ |
|
||||||
if (oldLength.IsAuto) { |
|
||||||
oldLength = new GridLength(oldActualValue); |
|
||||||
} |
|
||||||
double percentage = insertionPosition / oldActualValue; |
|
||||||
newLength1 = new GridLength(oldLength.Value * percentage, oldLength.GridUnitType); |
|
||||||
newLength2 = new GridLength(oldLength.Value - newLength1.Value, oldLength.GridUnitType); |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
} |
|
||||||
|
|
||||||
public abstract class GridSplitterAdorner : Control |
|
||||||
{ |
|
||||||
public static readonly DependencyProperty IsPreviewProperty |
|
||||||
= DependencyProperty.Register("IsPreview", typeof(bool), typeof(GridSplitterAdorner), new PropertyMetadata(SharedInstances.BoxedFalse)); |
|
||||||
|
|
||||||
protected readonly Grid grid; |
|
||||||
protected readonly DesignItem gridItem; |
|
||||||
protected readonly DesignItem firstRow, secondRow; // can also be columns
|
|
||||||
|
|
||||||
internal GridSplitterAdorner(DesignItem gridItem, DesignItem firstRow, DesignItem secondRow) |
|
||||||
{ |
|
||||||
Debug.Assert(gridItem != null); |
|
||||||
this.grid = (Grid)gridItem.Component; |
|
||||||
this.gridItem = gridItem; |
|
||||||
this.firstRow = firstRow; |
|
||||||
this.secondRow = secondRow; |
|
||||||
} |
|
||||||
|
|
||||||
public bool IsPreview { |
|
||||||
get { return (bool)GetValue(IsPreviewProperty); } |
|
||||||
set { SetValue(IsPreviewProperty, SharedInstances.Box(value)); } |
|
||||||
} |
|
||||||
|
|
||||||
ChangeGroup activeChangeGroup; |
|
||||||
double mouseStartPos; |
|
||||||
bool mouseIsDown; |
|
||||||
|
|
||||||
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
e.Handled = true; |
|
||||||
if (CaptureMouse()) { |
|
||||||
Focus(); |
|
||||||
gridItem.Services.Selection.SetSelectedComponents(new DesignItem[] { secondRow }, SelectionTypes.Auto); |
|
||||||
mouseStartPos = GetCoordinate(e.GetPosition(grid)); |
|
||||||
mouseIsDown = true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseMove(MouseEventArgs e) |
|
||||||
{ |
|
||||||
if (mouseIsDown) { |
|
||||||
double mousePos = GetCoordinate(e.GetPosition(grid)); |
|
||||||
if (activeChangeGroup == null) { |
|
||||||
if (Math.Abs(mousePos - mouseStartPos) |
|
||||||
>= GetCoordinate(new Point(SystemParameters.MinimumHorizontalDragDistance, SystemParameters.MinimumVerticalDragDistance))) { |
|
||||||
activeChangeGroup = gridItem.OpenGroup("Change grid row/column size"); |
|
||||||
RememberOriginalSize(); |
|
||||||
} |
|
||||||
} |
|
||||||
if (activeChangeGroup != null) { |
|
||||||
ChangeSize(mousePos - mouseStartPos); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected GridLength original1, original2; |
|
||||||
protected double originalPixelSize1, originalPixelSize2; |
|
||||||
|
|
||||||
protected abstract double GetCoordinate(Point point); |
|
||||||
protected abstract void RememberOriginalSize(); |
|
||||||
protected abstract DependencyProperty RowColumnSizeProperty { get; } |
|
||||||
|
|
||||||
void ChangeSize(double delta) |
|
||||||
{ |
|
||||||
// delta = difference in pixels
|
|
||||||
|
|
||||||
if (delta < -originalPixelSize1) delta = -originalPixelSize1; |
|
||||||
if (delta > originalPixelSize2) delta = originalPixelSize2; |
|
||||||
|
|
||||||
// replace Auto lengths with absolute lengths if necessary
|
|
||||||
if (original1.IsAuto) original1 = new GridLength(originalPixelSize1); |
|
||||||
if (original2.IsAuto) original2 = new GridLength(originalPixelSize2); |
|
||||||
|
|
||||||
GridLength new1; |
|
||||||
if (original1.IsStar && originalPixelSize1 > 0) |
|
||||||
new1 = new GridLength(original1.Value * (originalPixelSize1 + delta) / originalPixelSize1, GridUnitType.Star); |
|
||||||
else |
|
||||||
new1 = new GridLength(originalPixelSize1 + delta); |
|
||||||
GridLength new2; |
|
||||||
if (original2.IsStar && originalPixelSize2 > 0) |
|
||||||
new2 = new GridLength(original2.Value * (originalPixelSize2 - delta) / originalPixelSize2, GridUnitType.Star); |
|
||||||
else |
|
||||||
new2 = new GridLength(originalPixelSize2 - delta); |
|
||||||
firstRow.Properties[RowColumnSizeProperty].SetValue(new1); |
|
||||||
secondRow.Properties[RowColumnSizeProperty].SetValue(new2); |
|
||||||
((UIElement)VisualTreeHelper.GetParent(this)).InvalidateArrange(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseUp(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
if (activeChangeGroup != null) { |
|
||||||
activeChangeGroup.Commit(); |
|
||||||
activeChangeGroup = null; |
|
||||||
} |
|
||||||
Stop(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnLostMouseCapture(MouseEventArgs e) |
|
||||||
{ |
|
||||||
Stop(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnKeyDown(KeyEventArgs e) |
|
||||||
{ |
|
||||||
if (e.Key == Key.Escape) { |
|
||||||
e.Handled = true; |
|
||||||
Stop(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected void Stop() |
|
||||||
{ |
|
||||||
ReleaseMouseCapture(); |
|
||||||
mouseIsDown = false; |
|
||||||
if (activeChangeGroup != null) { |
|
||||||
activeChangeGroup.Abort(); |
|
||||||
activeChangeGroup = null; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class GridRowSplitterAdorner : GridSplitterAdorner |
|
||||||
{ |
|
||||||
static GridRowSplitterAdorner() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(GridRowSplitterAdorner), new FrameworkPropertyMetadata(typeof(GridRowSplitterAdorner))); |
|
||||||
CursorProperty.OverrideMetadata(typeof(GridRowSplitterAdorner), new FrameworkPropertyMetadata(Cursors.SizeNS)); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
internal GridRowSplitterAdorner(DesignItem gridItem, DesignItem firstRow, DesignItem secondRow) : base(gridItem, firstRow, secondRow) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
protected override double GetCoordinate(Point point) |
|
||||||
{ |
|
||||||
return point.Y; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void RememberOriginalSize() |
|
||||||
{ |
|
||||||
RowDefinition r1 = (RowDefinition)firstRow.Component; |
|
||||||
RowDefinition r2 = (RowDefinition)secondRow.Component; |
|
||||||
original1 = (GridLength)r1.GetValue(RowDefinition.HeightProperty); |
|
||||||
original2 = (GridLength)r2.GetValue(RowDefinition.HeightProperty); |
|
||||||
originalPixelSize1 = r1.ActualHeight; |
|
||||||
originalPixelSize2 = r2.ActualHeight; |
|
||||||
} |
|
||||||
|
|
||||||
protected override DependencyProperty RowColumnSizeProperty { |
|
||||||
get { return RowDefinition.HeightProperty; } |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public sealed class GridColumnSplitterAdorner : GridSplitterAdorner |
|
||||||
{ |
|
||||||
static GridColumnSplitterAdorner() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(GridColumnSplitterAdorner), new FrameworkPropertyMetadata(typeof(GridColumnSplitterAdorner))); |
|
||||||
CursorProperty.OverrideMetadata(typeof(GridColumnSplitterAdorner), new FrameworkPropertyMetadata(Cursors.SizeWE)); |
|
||||||
} |
|
||||||
|
|
||||||
internal GridColumnSplitterAdorner(DesignItem gridItem, DesignItem firstRow, DesignItem secondRow) : base(gridItem, firstRow, secondRow) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
protected override double GetCoordinate(Point point) |
|
||||||
{ |
|
||||||
return point.X; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void RememberOriginalSize() |
|
||||||
{ |
|
||||||
ColumnDefinition r1 = (ColumnDefinition)firstRow.Component; |
|
||||||
ColumnDefinition r2 = (ColumnDefinition)secondRow.Component; |
|
||||||
original1 = (GridLength)r1.GetValue(ColumnDefinition.WidthProperty); |
|
||||||
original2 = (GridLength)r2.GetValue(ColumnDefinition.WidthProperty); |
|
||||||
originalPixelSize1 = r1.ActualWidth; |
|
||||||
originalPixelSize2 = r2.ActualWidth; |
|
||||||
} |
|
||||||
|
|
||||||
protected override DependencyProperty RowColumnSizeProperty { |
|
||||||
get { return ColumnDefinition.WidthProperty; } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,302 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
using System.Globalization; |
|
||||||
using System.Diagnostics; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
public class NumericUpDown : Control |
|
||||||
{ |
|
||||||
static NumericUpDown() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericUpDown), |
|
||||||
new FrameworkPropertyMetadata(typeof(NumericUpDown))); |
|
||||||
} |
|
||||||
|
|
||||||
TextBox textBox; |
|
||||||
DragRepeatButton upButton; |
|
||||||
DragRepeatButton downButton; |
|
||||||
|
|
||||||
public static readonly DependencyProperty DecimalPlacesProperty = |
|
||||||
DependencyProperty.Register("DecimalPlaces", typeof(int), typeof(NumericUpDown)); |
|
||||||
|
|
||||||
public int DecimalPlaces { |
|
||||||
get { return (int)GetValue(DecimalPlacesProperty); } |
|
||||||
set { SetValue(DecimalPlacesProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty MinimumProperty = |
|
||||||
DependencyProperty.Register("Minimum", typeof(double), typeof(NumericUpDown)); |
|
||||||
|
|
||||||
public double Minimum { |
|
||||||
get { return (double)GetValue(MinimumProperty); } |
|
||||||
set { SetValue(MinimumProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty MaximumProperty = |
|
||||||
DependencyProperty.Register("Maximum", typeof(double), typeof(NumericUpDown), |
|
||||||
new FrameworkPropertyMetadata(100.0)); |
|
||||||
|
|
||||||
public double Maximum { |
|
||||||
get { return (double)GetValue(MaximumProperty); } |
|
||||||
set { SetValue(MaximumProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty ValueProperty = |
|
||||||
DependencyProperty.Register("Value", typeof(double), typeof(NumericUpDown), |
|
||||||
new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); |
|
||||||
|
|
||||||
public double Value { |
|
||||||
get { return (double)GetValue(ValueProperty); } |
|
||||||
set { SetValue(ValueProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty SmallChangeProperty = |
|
||||||
DependencyProperty.Register("SmallChange", typeof(double), typeof(NumericUpDown), |
|
||||||
new FrameworkPropertyMetadata(1.0)); |
|
||||||
|
|
||||||
public double SmallChange { |
|
||||||
get { return (double)GetValue(SmallChangeProperty); } |
|
||||||
set { SetValue(SmallChangeProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty LargeChangeProperty = |
|
||||||
DependencyProperty.Register("LargeChange", typeof(double), typeof(NumericUpDown), |
|
||||||
new FrameworkPropertyMetadata(10.0)); |
|
||||||
|
|
||||||
public double LargeChange { |
|
||||||
get { return (double)GetValue(LargeChangeProperty); } |
|
||||||
set { SetValue(LargeChangeProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
bool IsDragging { |
|
||||||
get { |
|
||||||
return upButton.IsDragging; |
|
||||||
} |
|
||||||
set { |
|
||||||
upButton.IsDragging = value; downButton.IsDragging = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override void OnApplyTemplate() |
|
||||||
{ |
|
||||||
base.OnApplyTemplate(); |
|
||||||
|
|
||||||
upButton = (DragRepeatButton)Template.FindName("PART_UpButton", this); |
|
||||||
downButton = (DragRepeatButton)Template.FindName("PART_DownButton", this); |
|
||||||
textBox = (TextBox)Template.FindName("PART_TextBox", this); |
|
||||||
|
|
||||||
upButton.Click += new RoutedEventHandler(upButton_Click); |
|
||||||
downButton.Click += new RoutedEventHandler(downButton_Click); |
|
||||||
|
|
||||||
var upDrag = new DragListener(upButton); |
|
||||||
var downDrag = new DragListener(downButton); |
|
||||||
|
|
||||||
upDrag.Started += drag_Started; |
|
||||||
upDrag.Changed += drag_Changed; |
|
||||||
upDrag.Completed += drag_Completed; |
|
||||||
|
|
||||||
downDrag.Started += drag_Started; |
|
||||||
downDrag.Changed += drag_Changed; |
|
||||||
downDrag.Completed += drag_Completed; |
|
||||||
|
|
||||||
Print(); |
|
||||||
} |
|
||||||
|
|
||||||
void drag_Started(DragListener drag) |
|
||||||
{ |
|
||||||
OnDragStarted(); |
|
||||||
} |
|
||||||
|
|
||||||
void drag_Changed(DragListener drag) |
|
||||||
{ |
|
||||||
IsDragging = true; |
|
||||||
MoveValue(-drag.DeltaDelta.Y * SmallChange); |
|
||||||
} |
|
||||||
|
|
||||||
void drag_Completed(DragListener drag) |
|
||||||
{ |
|
||||||
IsDragging = false; |
|
||||||
OnDragCompleted(); |
|
||||||
} |
|
||||||
|
|
||||||
void downButton_Click(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
if (!IsDragging) SmallDown(); |
|
||||||
} |
|
||||||
|
|
||||||
void upButton_Click(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
if (!IsDragging) SmallUp(); |
|
||||||
} |
|
||||||
|
|
||||||
protected virtual void OnDragStarted() |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
protected virtual void OnDragCompleted() |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public void SmallUp() |
|
||||||
{ |
|
||||||
MoveValue(SmallChange); |
|
||||||
} |
|
||||||
|
|
||||||
public void SmallDown() |
|
||||||
{ |
|
||||||
MoveValue(-SmallChange); |
|
||||||
} |
|
||||||
|
|
||||||
public void LargeUp() |
|
||||||
{ |
|
||||||
MoveValue(LargeChange); |
|
||||||
} |
|
||||||
|
|
||||||
public void LargeDown() |
|
||||||
{ |
|
||||||
MoveValue(-LargeChange); |
|
||||||
} |
|
||||||
|
|
||||||
void MoveValue(double delta) |
|
||||||
{ |
|
||||||
double result; |
|
||||||
if (double.IsNaN(Value) || double.IsInfinity(Value)) { |
|
||||||
SetValue(delta); |
|
||||||
} |
|
||||||
else if (double.TryParse(textBox.Text, out result)) { |
|
||||||
SetValue(result + delta); |
|
||||||
} |
|
||||||
else { |
|
||||||
SetValue(Value + delta); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void Print() |
|
||||||
{ |
|
||||||
if (textBox != null) { |
|
||||||
textBox.Text = Value.ToString("F" + DecimalPlaces); |
|
||||||
textBox.CaretIndex = int.MaxValue; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
//wpf bug?: Value = -1 updates bindings without coercing, workaround
|
|
||||||
//update: not derived from RangeBase - no problem
|
|
||||||
void SetValue(double newValue) |
|
||||||
{ |
|
||||||
newValue = CoerceValue(newValue); |
|
||||||
if (Value != newValue) { |
|
||||||
Value = newValue; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
double CoerceValue(double newValue) |
|
||||||
{ |
|
||||||
return Math.Max(Minimum, Math.Min(newValue, Maximum)); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPreviewKeyDown(KeyEventArgs e) |
|
||||||
{ |
|
||||||
base.OnPreviewKeyDown(e); |
|
||||||
if (e.Key == Key.Enter) { |
|
||||||
double result; |
|
||||||
if (double.TryParse(textBox.Text, out result)) { |
|
||||||
SetValue(result); |
|
||||||
} |
|
||||||
else { |
|
||||||
Print(); |
|
||||||
} |
|
||||||
textBox.SelectAll(); |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
else if (e.Key == Key.Up) { |
|
||||||
SmallUp(); |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
else if (e.Key == Key.Down) { |
|
||||||
SmallDown(); |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
else if (e.Key == Key.PageUp) { |
|
||||||
LargeUp(); |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
else if (e.Key == Key.PageDown) { |
|
||||||
LargeDown(); |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
//else if (e.Key == Key.Home) {
|
|
||||||
// Maximize();
|
|
||||||
// e.Handled = true;
|
|
||||||
//}
|
|
||||||
//else if (e.Key == Key.End) {
|
|
||||||
// Minimize();
|
|
||||||
// e.Handled = true;
|
|
||||||
//}
|
|
||||||
} |
|
||||||
|
|
||||||
//protected override void OnMouseWheel(MouseWheelEventArgs e)
|
|
||||||
//{
|
|
||||||
// if (e.Delta > 0)
|
|
||||||
// {
|
|
||||||
// if (Keyboard.IsKeyDown(Key.LeftShift))
|
|
||||||
// {
|
|
||||||
// LargeUp();
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// SmallUp();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// if (Keyboard.IsKeyDown(Key.LeftShift))
|
|
||||||
// {
|
|
||||||
// LargeDown();
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// SmallDown();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// e.Handled = true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
base.OnPropertyChanged(e); |
|
||||||
|
|
||||||
if (e.Property == ValueProperty) { |
|
||||||
Value = CoerceValue((double)e.NewValue); |
|
||||||
Print(); |
|
||||||
} |
|
||||||
else if (e.Property == SmallChangeProperty && |
|
||||||
ReadLocalValue(LargeChangeProperty) == DependencyProperty.UnsetValue) { |
|
||||||
LargeChange = SmallChange * 10; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class DragRepeatButton : RepeatButton |
|
||||||
{ |
|
||||||
public static readonly DependencyProperty IsDraggingProperty = |
|
||||||
DependencyProperty.Register("IsDragging", typeof(bool), typeof(DragRepeatButton)); |
|
||||||
|
|
||||||
public bool IsDragging { |
|
||||||
get { return (bool)GetValue(IsDraggingProperty); } |
|
||||||
set { SetValue(IsDraggingProperty, value); } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,149 +0,0 @@ |
|||||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:Controls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls" |
|
||||||
xmlns:BrushEditor="clr-namespace:ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor"> |
|
||||||
|
|
||||||
<!--<Brush x:Key="ButtonNormal">#C3D3FD</Brush> |
|
||||||
<Brush x:Key="ButtonHover">#D7ECFC</Brush> |
|
||||||
<Brush x:Key="ButtonPressed">#92AAF0</Brush> |
|
||||||
<Brush x:Key="BorderBrush">#FF7F9DB9</Brush> |
|
||||||
<Brush x:Key="ArrowBrush">#4D6185</Brush> |
|
||||||
<Brush x:Key="ArrowsBorderBrush">#B4C8F6</Brush>--> |
|
||||||
|
|
||||||
<Brush x:Key="ButtonNormal">#DADFEA</Brush> |
|
||||||
<Brush x:Key="ButtonHover">#E6EBEF</Brush> |
|
||||||
<Brush x:Key="ButtonPressed">#B6BDD3</Brush> |
|
||||||
<Brush x:Key="BorderBrush">#7F9DB9</Brush> |
|
||||||
<Brush x:Key="ArrowBrush">Black</Brush> |
|
||||||
<Brush x:Key="ArrowsBorderBrush">#B6BDD3</Brush> |
|
||||||
|
|
||||||
<Style x:Key="UpButton" |
|
||||||
TargetType="RepeatButton"> |
|
||||||
<Setter Property="Focusable" |
|
||||||
Value="False" /> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:DragRepeatButton}"> |
|
||||||
<Border x:Name="bg" |
|
||||||
Background="{StaticResource ButtonNormal}" |
|
||||||
CornerRadius="2 2 0 0"> |
|
||||||
<Path Fill="{StaticResource ArrowBrush}" |
|
||||||
Data="M 0 3 L 3.5 0 L 7 3" |
|
||||||
HorizontalAlignment="Center" |
|
||||||
VerticalAlignment="Center" /> |
|
||||||
</Border> |
|
||||||
<ControlTemplate.Triggers> |
|
||||||
<Trigger Property="IsMouseOver" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="bg" |
|
||||||
Property="Background" |
|
||||||
Value="{StaticResource ButtonHover}" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="IsMouseCaptured" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="bg" |
|
||||||
Property="Background" |
|
||||||
Value="{StaticResource ButtonPressed}" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="IsDragging" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="bg" |
|
||||||
Property="Background" |
|
||||||
Value="{StaticResource ButtonPressed}" /> |
|
||||||
</Trigger> |
|
||||||
</ControlTemplate.Triggers> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style x:Key="DownButton" |
|
||||||
TargetType="RepeatButton"> |
|
||||||
<Setter Property="Focusable" |
|
||||||
Value="False" /> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:DragRepeatButton}"> |
|
||||||
<Border x:Name="bg" |
|
||||||
Background="{StaticResource ButtonNormal}" |
|
||||||
CornerRadius="0 0 2 2"> |
|
||||||
<Path Fill="{StaticResource ArrowBrush}" |
|
||||||
Data="M 0 0 L 3.5 3 L 7 0" |
|
||||||
HorizontalAlignment="Center" |
|
||||||
VerticalAlignment="Center" /> |
|
||||||
</Border> |
|
||||||
<ControlTemplate.Triggers> |
|
||||||
<Trigger Property="IsMouseOver" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="bg" |
|
||||||
Property="Background" |
|
||||||
Value="{StaticResource ButtonHover}" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="IsMouseCaptured" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="bg" |
|
||||||
Property="Background" |
|
||||||
Value="{StaticResource ButtonPressed}" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="IsDragging" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="bg" |
|
||||||
Property="Background" |
|
||||||
Value="{StaticResource ButtonPressed}" /> |
|
||||||
</Trigger> |
|
||||||
</ControlTemplate.Triggers> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Controls:NumericUpDown}"> |
|
||||||
<Setter Property="Background" |
|
||||||
Value="White" /> |
|
||||||
<Setter Property="BorderThickness" |
|
||||||
Value="1" /> |
|
||||||
<Setter Property="BorderBrush" |
|
||||||
Value="{StaticResource BorderBrush}" /> |
|
||||||
<Setter Property="Focusable" |
|
||||||
Value="False" /> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Controls:NumericUpDown}"> |
|
||||||
<Border Background="{TemplateBinding Background}" |
|
||||||
BorderBrush="{TemplateBinding BorderBrush}" |
|
||||||
BorderThickness="{TemplateBinding BorderThickness}" |
|
||||||
Padding="1"> |
|
||||||
<Grid> |
|
||||||
<Grid.RowDefinitions> |
|
||||||
<RowDefinition /> |
|
||||||
<RowDefinition /> |
|
||||||
</Grid.RowDefinitions> |
|
||||||
<Grid.ColumnDefinitions> |
|
||||||
<ColumnDefinition /> |
|
||||||
<ColumnDefinition Width="15" /> |
|
||||||
</Grid.ColumnDefinitions> |
|
||||||
<TextBox x:Name="PART_TextBox" |
|
||||||
BorderThickness="0" |
|
||||||
Background="{x:Null}" |
|
||||||
Foreground="{TemplateBinding Foreground}" |
|
||||||
Grid.RowSpan="2" /> |
|
||||||
<Controls:DragRepeatButton x:Name="PART_UpButton" |
|
||||||
Style="{StaticResource UpButton}" |
|
||||||
Grid.Column="1" /> |
|
||||||
<Controls:DragRepeatButton x:Name="PART_DownButton" |
|
||||||
Style="{StaticResource DownButton}" |
|
||||||
Grid.Column="1" |
|
||||||
Grid.Row="1" /> |
|
||||||
<Border Grid.Column="1" |
|
||||||
Grid.RowSpan="2" |
|
||||||
BorderBrush="{StaticResource ArrowsBorderBrush}" |
|
||||||
BorderThickness="1" |
|
||||||
CornerRadius="2" /> |
|
||||||
</Grid> |
|
||||||
</Border> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
</ResourceDictionary> |
|
||||||
@ -1,34 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Input; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Services; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
public class PanelMoveAdorner : Control |
|
||||||
{ |
|
||||||
static PanelMoveAdorner() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(PanelMoveAdorner), |
|
||||||
new FrameworkPropertyMetadata(typeof(PanelMoveAdorner))); |
|
||||||
} |
|
||||||
|
|
||||||
public PanelMoveAdorner(DesignItem item) |
|
||||||
{ |
|
||||||
this.item = item; |
|
||||||
} |
|
||||||
|
|
||||||
DesignItem item; |
|
||||||
|
|
||||||
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
e.Handled = true; |
|
||||||
item.Services.Selection.SetSelectedComponents(new DesignItem [] { item }, SelectionTypes.Auto); |
|
||||||
new DragMoveMouseGesture(item, false).Start(item.Services.DesignPanel, e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,89 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// A thumb where the look can depend on the IsPrimarySelection property.
|
|
||||||
/// </summary>
|
|
||||||
public class ResizeThumb : Thumb |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Dependency property for <see cref="IsPrimarySelection"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly DependencyProperty IsPrimarySelectionProperty |
|
||||||
= DependencyProperty.Register("IsPrimarySelection", typeof(bool), typeof(ResizeThumb)); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Dependency property for <see cref="IsPrimarySelection"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly DependencyProperty ResizeThumbVisibleProperty |
|
||||||
= DependencyProperty.Register("ResizeThumbVisible", typeof(bool), typeof(ResizeThumb), new FrameworkPropertyMetadata(true)); |
|
||||||
|
|
||||||
internal PlacementAlignment Alignment; |
|
||||||
|
|
||||||
static ResizeThumb() |
|
||||||
{ |
|
||||||
//This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
|
|
||||||
//This style is defined in themes\generic.xaml
|
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ResizeThumb), new FrameworkPropertyMetadata(typeof(ResizeThumb))); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets/Sets if the resize thumb is attached to the primary selection.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsPrimarySelection { |
|
||||||
get { return (bool)GetValue(IsPrimarySelectionProperty); } |
|
||||||
set { SetValue(IsPrimarySelectionProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets/Sets if the resize thumb is visible.
|
|
||||||
/// </summary>
|
|
||||||
public bool ResizeThumbVisible { |
|
||||||
get { return (bool)GetValue(ResizeThumbVisibleProperty); } |
|
||||||
set { SetValue(ResizeThumbVisibleProperty, value); } |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Resize thumb that automatically disappears if the adornered element is too small.
|
|
||||||
/// </summary>
|
|
||||||
sealed class ResizeThumbImpl : ResizeThumb |
|
||||||
{ |
|
||||||
bool checkWidth, checkHeight; |
|
||||||
|
|
||||||
internal ResizeThumbImpl(bool checkWidth, bool checkHeight) |
|
||||||
{ |
|
||||||
Debug.Assert((checkWidth && checkHeight) == false); |
|
||||||
this.checkWidth = checkWidth; |
|
||||||
this.checkHeight = checkHeight; |
|
||||||
} |
|
||||||
|
|
||||||
protected override Size ArrangeOverride(Size arrangeBounds) |
|
||||||
{ |
|
||||||
AdornerPanel parent = this.Parent as AdornerPanel; |
|
||||||
if (parent != null && parent.AdornedElement != null) { |
|
||||||
if (checkWidth) |
|
||||||
this.ResizeThumbVisible = parent.AdornedElement.RenderSize.Width > 14; |
|
||||||
else if (checkHeight) |
|
||||||
this.ResizeThumbVisible = parent.AdornedElement.RenderSize.Height > 14; |
|
||||||
} |
|
||||||
return base.ArrangeOverride(arrangeBounds); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,32 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.ComponentModel; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// The rectangle shown during a rubber-band selecting operation.
|
|
||||||
/// </summary>
|
|
||||||
public class SelectionFrame : Control |
|
||||||
{ |
|
||||||
static SelectionFrame() |
|
||||||
{ |
|
||||||
//This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
|
|
||||||
//This style is defined in themes\generic.xaml
|
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(SelectionFrame), new FrameworkPropertyMetadata(typeof(SelectionFrame))); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,228 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.ComponentModel; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// A custom control that imitates the properties of <see cref="Window"/>, but is not a top-level control.
|
|
||||||
/// </summary>
|
|
||||||
public class WindowClone : ContentControl |
|
||||||
{ |
|
||||||
static WindowClone() |
|
||||||
{ |
|
||||||
//This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
|
|
||||||
//This style is defined in themes\generic.xaml
|
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(typeof(WindowClone))); |
|
||||||
|
|
||||||
Control.IsTabStopProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(SharedInstances.BoxedFalse)); |
|
||||||
KeyboardNavigation.DirectionalNavigationProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(KeyboardNavigationMode.Cycle)); |
|
||||||
KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(KeyboardNavigationMode.Cycle)); |
|
||||||
KeyboardNavigation.ControlTabNavigationProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(KeyboardNavigationMode.Cycle)); |
|
||||||
FocusManager.IsFocusScopeProperty.OverrideMetadata(typeof(WindowClone), new FrameworkPropertyMetadata(SharedInstances.BoxedTrue)); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This property has no effect. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public bool AllowsTransparency { |
|
||||||
get { return (bool)GetValue(Window.AllowsTransparencyProperty); } |
|
||||||
set { SetValue(Window.AllowsTransparencyProperty, SharedInstances.Box(value)); } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This property has no effect. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), TypeConverter(typeof(DialogResultConverter))] |
|
||||||
public bool? DialogResult { |
|
||||||
get { |
|
||||||
return null; |
|
||||||
} |
|
||||||
set { } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the icon to use.
|
|
||||||
/// </summary>
|
|
||||||
public ImageSource Icon { |
|
||||||
get { return (ImageSource)GetValue(Window.IconProperty); } |
|
||||||
set { SetValue(Window.IconProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This property has no effect. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
[TypeConverter(typeof(LengthConverter))] |
|
||||||
public double Left { |
|
||||||
get { return (double)GetValue(Window.LeftProperty); } |
|
||||||
set { SetValue(Window.LeftProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
Window owner; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This property has no effect. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public Window Owner { |
|
||||||
get { return owner; } |
|
||||||
set { owner = value; } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the resize mode.
|
|
||||||
/// </summary>
|
|
||||||
public ResizeMode ResizeMode { |
|
||||||
get { return (ResizeMode)GetValue(Window.ResizeModeProperty); } |
|
||||||
set { SetValue(Window.ResizeModeProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty ShowActivatedProperty = |
|
||||||
DependencyProperty.Register("ShowActivated", typeof(bool), typeof(WindowClone)); |
|
||||||
|
|
||||||
public bool ShowActivated { |
|
||||||
get { return (bool)GetValue(ShowActivatedProperty); } |
|
||||||
set { SetValue(ShowActivatedProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This property has no effect. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public bool ShowInTaskbar { |
|
||||||
get { return (bool)GetValue(Window.ShowInTaskbarProperty); } |
|
||||||
set { SetValue(Window.ShowInTaskbarProperty, SharedInstances.Box(value)); } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value that specifies whether a window will automatically size itself to fit the size of its content.
|
|
||||||
/// </summary>
|
|
||||||
public SizeToContent SizeToContent { |
|
||||||
get { return (SizeToContent)GetValue(Window.SizeToContentProperty); } |
|
||||||
set { SetValue(Window.SizeToContentProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The title to display in the Window's title bar.
|
|
||||||
/// </summary>
|
|
||||||
public string Title { |
|
||||||
get { return (string)GetValue(Window.TitleProperty); } |
|
||||||
set { SetValue(Window.TitleProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This property has no effect. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
[TypeConverter(typeof(LengthConverter))] |
|
||||||
public double Top { |
|
||||||
get { return (double)GetValue(Window.TopProperty); } |
|
||||||
set { SetValue(Window.TopProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This property has no effect. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public bool Topmost { |
|
||||||
get { return (bool)GetValue(Window.TopmostProperty); } |
|
||||||
set { SetValue(Window.TopmostProperty, SharedInstances.Box(value)); } |
|
||||||
} |
|
||||||
|
|
||||||
WindowStartupLocation windowStartupLocation; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This property has no effect. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public WindowStartupLocation WindowStartupLocation { |
|
||||||
get { return windowStartupLocation; } |
|
||||||
set { windowStartupLocation = value; } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This property has no effect. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public WindowState WindowState { |
|
||||||
get { return (WindowState) GetValue(Window.WindowStateProperty); } |
|
||||||
set { SetValue(Window.WindowStateProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This property has no effect. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public WindowStyle WindowStyle { |
|
||||||
get { return (WindowStyle)GetValue(Window.WindowStyleProperty); } |
|
||||||
set { SetValue(Window.WindowStyleProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
#pragma warning disable 0067
|
|
||||||
// disable "event is never used" warning
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This event is never raised. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler Activated; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This event is never raised. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler Closed; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This event is never raised. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler Closing; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This event is never raised. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler ContentRendered; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This event is never raised. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler Deactivated; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This event is never raised. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler LocationChanged; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This event is never raised. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler SourceInitialized; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This event is never raised. (for compatibility with <see cref="Window"/> only).
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler StateChanged; |
|
||||||
#pragma warning restore
|
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A <see cref="CustomInstanceFactory"/> for <see cref="Window"/>
|
|
||||||
/// (and derived classes, unless they specify their own <see cref="CustomInstanceFactory"/>).
|
|
||||||
/// </summary>
|
|
||||||
[ExtensionFor(typeof(Window))] |
|
||||||
public class WindowCloneExtension : CustomInstanceFactory |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Used to create instances of <see cref="WindowClone"/>.
|
|
||||||
/// </summary>
|
|
||||||
public override object CreateInstance(Type type, params object[] arguments) |
|
||||||
{ |
|
||||||
Debug.Assert(arguments.Length == 0); |
|
||||||
return new WindowClone(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,200 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
using System.IO; |
|
||||||
using System.Reflection; |
|
||||||
using System.Resources; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
|
||||||
{ |
|
||||||
public class ZoomControl : ContentControl |
|
||||||
{ |
|
||||||
static ZoomControl() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ZoomControl), |
|
||||||
new FrameworkPropertyMetadata(typeof(ZoomControl))); |
|
||||||
|
|
||||||
PanToolCursor = new Cursor(GetStream("Images/PanToolCursor.cur")); |
|
||||||
PanToolCursorMouseDown = new Cursor(GetStream("Images/PanToolCursorMouseDown.cur")); |
|
||||||
} |
|
||||||
|
|
||||||
static Stream GetStream(string path) |
|
||||||
{ |
|
||||||
var a = Assembly.GetExecutingAssembly(); |
|
||||||
var m = new ResourceManager(a.GetName().Name + ".g", a); |
|
||||||
var s = m.GetStream(path.ToLower()); |
|
||||||
return s; |
|
||||||
} |
|
||||||
|
|
||||||
static Cursor PanToolCursor; |
|
||||||
static Cursor PanToolCursorMouseDown; |
|
||||||
public static double ZoomFactor = 1.1; |
|
||||||
public static double Minimum = 0.1; |
|
||||||
public static double Maximum = 10; |
|
||||||
|
|
||||||
double startHorizontalOffset; |
|
||||||
double startVericalOffset; |
|
||||||
|
|
||||||
internal ScrollViewer ScrollViewer; |
|
||||||
Border container; |
|
||||||
ScaleTransform transform; |
|
||||||
Point startPoint; |
|
||||||
bool isMouseDown; |
|
||||||
bool pan; |
|
||||||
|
|
||||||
public static readonly DependencyProperty ZoomProperty = |
|
||||||
DependencyProperty.Register("Zoom", typeof(double), typeof(ZoomControl), |
|
||||||
new PropertyMetadata(1.0, null, CoerceZoom)); |
|
||||||
|
|
||||||
public double Zoom |
|
||||||
{ |
|
||||||
get { return (double)GetValue(ZoomProperty); } |
|
||||||
set { SetValue(ZoomProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
static object CoerceZoom(DependencyObject d, object baseValue) |
|
||||||
{ |
|
||||||
var zoom = (double)baseValue; |
|
||||||
return Math.Max(Minimum, Math.Min(Maximum, zoom)); |
|
||||||
} |
|
||||||
|
|
||||||
public override void OnApplyTemplate() |
|
||||||
{ |
|
||||||
base.OnApplyTemplate(); |
|
||||||
|
|
||||||
ScrollViewer = (ScrollViewer)Template.FindName("scrollViewer", this); |
|
||||||
container = (Border)Template.FindName("container", this); |
|
||||||
transform = new ScaleTransform(); |
|
||||||
container.LayoutTransform = transform; |
|
||||||
|
|
||||||
var uxPlus = (ButtonBase)Template.FindName("uxPlus", this); |
|
||||||
var uxMinus = (ButtonBase)Template.FindName("uxMinus", this); |
|
||||||
var uxReset = (ButtonBase)Template.FindName("uxReset", this); |
|
||||||
|
|
||||||
uxPlus.Click += delegate { ZoomIn(); }; |
|
||||||
uxMinus.Click += delegate { ZoomOut(); }; |
|
||||||
uxReset.Click += delegate { Reset(); }; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
base.OnPropertyChanged(e); |
|
||||||
if (e.Property == ZoomProperty) |
|
||||||
{ |
|
||||||
transform.ScaleX = Zoom; |
|
||||||
transform.ScaleY = Zoom; |
|
||||||
CenterViewport((double)e.OldValue); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnKeyDown(KeyEventArgs e) |
|
||||||
{ |
|
||||||
if (!pan && e.Key == Key.Space) |
|
||||||
{ |
|
||||||
Cursor = PanToolCursor; |
|
||||||
pan = true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnKeyUp(KeyEventArgs e) |
|
||||||
{ |
|
||||||
if (e.Key == Key.Space) |
|
||||||
{ |
|
||||||
ClearValue(CursorProperty); |
|
||||||
pan = false; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPreviewMouseDown(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
if (pan) |
|
||||||
{ |
|
||||||
Cursor = PanToolCursorMouseDown; |
|
||||||
Mouse.Capture(this); // will call move
|
|
||||||
isMouseDown = true; |
|
||||||
startPoint = e.GetPosition(this); |
|
||||||
PanStart(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPreviewMouseMove(MouseEventArgs e) |
|
||||||
{ |
|
||||||
if (isMouseDown && pan) |
|
||||||
{ |
|
||||||
var endPoint = e.GetPosition(this); |
|
||||||
PanContinue(endPoint - startPoint); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPreviewMouseUp(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
if (isMouseDown) |
|
||||||
{ |
|
||||||
Cursor = PanToolCursor; |
|
||||||
isMouseDown = false; |
|
||||||
Mouse.Capture(null); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseEnter(MouseEventArgs e) |
|
||||||
{ |
|
||||||
Focus(); |
|
||||||
} |
|
||||||
|
|
||||||
public void Fit() |
|
||||||
{ |
|
||||||
Zoom = Math.Min( |
|
||||||
ScrollViewer.ActualWidth / container.ActualWidth, |
|
||||||
ScrollViewer.ActualHeight / container.ActualHeight); |
|
||||||
} |
|
||||||
|
|
||||||
public void ZoomIn() |
|
||||||
{ |
|
||||||
Zoom *= ZoomFactor; |
|
||||||
} |
|
||||||
|
|
||||||
public void ZoomOut() |
|
||||||
{ |
|
||||||
Zoom /= ZoomFactor; |
|
||||||
} |
|
||||||
|
|
||||||
public void Reset() |
|
||||||
{ |
|
||||||
Zoom = 1; |
|
||||||
ScrollViewer.ScrollToHorizontalOffset(0); |
|
||||||
ScrollViewer.ScrollToVerticalOffset(0); |
|
||||||
} |
|
||||||
|
|
||||||
void PanStart() |
|
||||||
{ |
|
||||||
startHorizontalOffset = ScrollViewer.HorizontalOffset; |
|
||||||
startVericalOffset = ScrollViewer.VerticalOffset; |
|
||||||
} |
|
||||||
|
|
||||||
void PanContinue(Vector delta) |
|
||||||
{ |
|
||||||
ScrollViewer.ScrollToHorizontalOffset(startHorizontalOffset - delta.X); |
|
||||||
ScrollViewer.ScrollToVerticalOffset(startVericalOffset - delta.Y); |
|
||||||
} |
|
||||||
|
|
||||||
void CenterViewport(double oldZoom) |
|
||||||
{ |
|
||||||
var k = Zoom / oldZoom; |
|
||||||
var add = (k * ScrollViewer.ViewportWidth - ScrollViewer.ViewportWidth) / 2; |
|
||||||
ScrollViewer.ScrollToHorizontalOffset(k * ScrollViewer.HorizontalOffset + add); |
|
||||||
add = (k * ScrollViewer.ViewportHeight - ScrollViewer.ViewportHeight) / 2; |
|
||||||
ScrollViewer.ScrollToVerticalOffset(k * ScrollViewer.VerticalOffset + add); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,135 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Globalization; |
|
||||||
using System.Windows; |
|
||||||
using System.Collections; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Converters |
|
||||||
{ |
|
||||||
public class IntFromEnumConverter : IValueConverter |
|
||||||
{ |
|
||||||
public static IntFromEnumConverter Instance = new IntFromEnumConverter(); |
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
return (int)value; |
|
||||||
} |
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
return Enum.ToObject(targetType, (int)value); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class HiddenWhenFalse : IValueConverter |
|
||||||
{ |
|
||||||
public static HiddenWhenFalse Instance = new HiddenWhenFalse(); |
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
return (bool)value ? Visibility.Visible : Visibility.Hidden; |
|
||||||
} |
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class CollapsedWhenFalse : IValueConverter |
|
||||||
{ |
|
||||||
public static CollapsedWhenFalse Instance = new CollapsedWhenFalse(); |
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
return (bool)value ? Visibility.Visible : Visibility.Collapsed; |
|
||||||
} |
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class LevelConverter : IValueConverter |
|
||||||
{ |
|
||||||
public static LevelConverter Instance = new LevelConverter(); |
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
return new Thickness(2 + 14 * (int)value, 0, 0, 0); |
|
||||||
} |
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class CollapsedWhenZero : IValueConverter |
|
||||||
{ |
|
||||||
public static CollapsedWhenZero Instance = new CollapsedWhenZero(); |
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
if (value == null || (int)value == 0) { |
|
||||||
return Visibility.Collapsed; |
|
||||||
} |
|
||||||
return Visibility.Visible; |
|
||||||
} |
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class FalseWhenNull : IValueConverter |
|
||||||
{ |
|
||||||
public static FalseWhenNull Instance = new FalseWhenNull(); |
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
return value != null; |
|
||||||
} |
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class BoldWhenTrue : IValueConverter |
|
||||||
{ |
|
||||||
public static BoldWhenTrue Instance = new BoldWhenTrue(); |
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
return (bool)value ? FontWeights.Bold : FontWeights.Normal; |
|
||||||
} |
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// Boxed int throw exception without converter (wpf bug?)
|
|
||||||
public class DummyConverter : IValueConverter |
|
||||||
{ |
|
||||||
public static DummyConverter Instance = new DummyConverter(); |
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
return value; |
|
||||||
} |
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
return value; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,270 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.ComponentModel; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Threading; |
|
||||||
|
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Controls; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer |
|
||||||
{ |
|
||||||
sealed class DesignPanel : Decorator, IDesignPanel |
|
||||||
{ |
|
||||||
#region Hit Testing
|
|
||||||
/// <summary>
|
|
||||||
/// this element is always hit (unless HitTestVisible is set to false)
|
|
||||||
/// </summary>
|
|
||||||
sealed class EatAllHitTestRequests : UIElement |
|
||||||
{ |
|
||||||
protected override GeometryHitTestResult HitTestCore(GeometryHitTestParameters hitTestParameters) |
|
||||||
{ |
|
||||||
return new GeometryHitTestResult(this, IntersectionDetail.FullyContains); |
|
||||||
} |
|
||||||
|
|
||||||
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) |
|
||||||
{ |
|
||||||
return new PointHitTestResult(this, hitTestParameters.HitPoint); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void RunHitTest(Visual reference, Point point, HitTestFilterCallback filterCallback, HitTestResultCallback resultCallback) |
|
||||||
{ |
|
||||||
VisualTreeHelper.HitTest(reference, filterCallback, resultCallback, |
|
||||||
new PointHitTestParameters(point)); |
|
||||||
} |
|
||||||
|
|
||||||
static HitTestFilterBehavior FilterHitTestInvisibleElements(DependencyObject potentialHitTestTarget) |
|
||||||
{ |
|
||||||
UIElement element = potentialHitTestTarget as UIElement; |
|
||||||
if (element != null) { |
|
||||||
if (!(element.IsHitTestVisible && element.Visibility == Visibility.Visible)) { |
|
||||||
return HitTestFilterBehavior.ContinueSkipSelfAndChildren; |
|
||||||
} |
|
||||||
} |
|
||||||
return HitTestFilterBehavior.Continue; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Performs a custom hit testing lookup for the specified mouse event args.
|
|
||||||
/// </summary>
|
|
||||||
public DesignPanelHitTestResult HitTest(Point mousePosition, bool testAdorners, bool testDesignSurface) |
|
||||||
{ |
|
||||||
DesignPanelHitTestResult result = DesignPanelHitTestResult.NoHit; |
|
||||||
HitTest(mousePosition, testAdorners, testDesignSurface, |
|
||||||
delegate(DesignPanelHitTestResult r) { |
|
||||||
result = r; |
|
||||||
return false; |
|
||||||
}); |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Performs a hit test on the design surface, raising <paramref name="callback"/> for each match.
|
|
||||||
/// Hit testing continues while the callback returns true.
|
|
||||||
/// </summary>
|
|
||||||
public void HitTest(Point mousePosition, bool testAdorners, bool testDesignSurface, Predicate<DesignPanelHitTestResult> callback) |
|
||||||
{ |
|
||||||
if (mousePosition.X < 0 || mousePosition.Y < 0 || mousePosition.X > this.RenderSize.Width || mousePosition.Y > this.RenderSize.Height) { |
|
||||||
return; |
|
||||||
} |
|
||||||
// First try hit-testing on the adorner layer.
|
|
||||||
|
|
||||||
bool continueHitTest = true; |
|
||||||
|
|
||||||
if (testAdorners) { |
|
||||||
RunHitTest( |
|
||||||
_adornerLayer, mousePosition, FilterHitTestInvisibleElements, |
|
||||||
delegate(HitTestResult result) { |
|
||||||
if (result != null && result.VisualHit != null && result.VisualHit is Visual) { |
|
||||||
DesignPanelHitTestResult customResult = new DesignPanelHitTestResult((Visual)result.VisualHit); |
|
||||||
DependencyObject obj = result.VisualHit; |
|
||||||
while (obj != null && obj != _adornerLayer) { |
|
||||||
AdornerPanel adorner = obj as AdornerPanel; |
|
||||||
if (adorner != null) { |
|
||||||
customResult.AdornerHit = adorner; |
|
||||||
} |
|
||||||
obj = VisualTreeHelper.GetParent(obj); |
|
||||||
} |
|
||||||
continueHitTest = callback(customResult); |
|
||||||
return continueHitTest ? HitTestResultBehavior.Continue : HitTestResultBehavior.Stop; |
|
||||||
} else { |
|
||||||
return HitTestResultBehavior.Continue; |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
if (continueHitTest && testDesignSurface) { |
|
||||||
RunHitTest( |
|
||||||
this.Child, mousePosition, delegate { return HitTestFilterBehavior.Continue; }, |
|
||||||
delegate(HitTestResult result) { |
|
||||||
if (result != null && result.VisualHit != null && result.VisualHit is Visual) { |
|
||||||
DesignPanelHitTestResult customResult = new DesignPanelHitTestResult((Visual)result.VisualHit); |
|
||||||
|
|
||||||
ViewService viewService = _context.Services.View; |
|
||||||
DependencyObject obj = result.VisualHit; |
|
||||||
while (obj != null) { |
|
||||||
if ((customResult.ModelHit = viewService.GetModel(obj)) != null) |
|
||||||
break; |
|
||||||
obj = VisualTreeHelper.GetParent(obj); |
|
||||||
} |
|
||||||
if (customResult.ModelHit == null) { |
|
||||||
customResult.ModelHit = _context.RootItem; |
|
||||||
} |
|
||||||
continueHitTest = callback(customResult); |
|
||||||
return continueHitTest ? HitTestResultBehavior.Continue : HitTestResultBehavior.Stop; |
|
||||||
} else { |
|
||||||
return HitTestResultBehavior.Continue; |
|
||||||
} |
|
||||||
} |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Fields + Constructor
|
|
||||||
DesignContext _context; |
|
||||||
readonly EatAllHitTestRequests _eatAllHitTestRequests; |
|
||||||
readonly AdornerLayer _adornerLayer; |
|
||||||
|
|
||||||
public DesignPanel() |
|
||||||
{ |
|
||||||
this.Focusable = true; |
|
||||||
this.VerticalAlignment = VerticalAlignment.Top; |
|
||||||
this.HorizontalAlignment = HorizontalAlignment.Left; |
|
||||||
this.AllowDrop = true; |
|
||||||
DesignerProperties.SetIsInDesignMode(this, true); |
|
||||||
|
|
||||||
_eatAllHitTestRequests = new EatAllHitTestRequests(); |
|
||||||
_eatAllHitTestRequests.MouseDown += delegate { |
|
||||||
// ensure the design panel has focus while the user is interacting with it
|
|
||||||
this.Focus(); |
|
||||||
}; |
|
||||||
_eatAllHitTestRequests.AllowDrop = true; |
|
||||||
_adornerLayer = new AdornerLayer(this); |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets/Sets the design context.
|
|
||||||
/// </summary>
|
|
||||||
public DesignContext Context { |
|
||||||
get { return _context; } |
|
||||||
set { _context = value; } |
|
||||||
} |
|
||||||
|
|
||||||
public ICollection<AdornerPanel> Adorners { |
|
||||||
get { |
|
||||||
return _adornerLayer.Adorners; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets/Sets if the design content is visible for hit-testing purposes.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsContentHitTestVisible { |
|
||||||
get { return !_eatAllHitTestRequests.IsHitTestVisible; } |
|
||||||
set { _eatAllHitTestRequests.IsHitTestVisible = !value; } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets/Sets if the adorner layer is visible for hit-testing purposes.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsAdornerLayerHitTestVisible { |
|
||||||
get { return _adornerLayer.IsHitTestVisible; } |
|
||||||
set { _adornerLayer.IsHitTestVisible = value; } |
|
||||||
} |
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Visual Child Management
|
|
||||||
public override UIElement Child { |
|
||||||
get { return base.Child; } |
|
||||||
set { |
|
||||||
if (base.Child == value) |
|
||||||
return; |
|
||||||
if (value == null) { |
|
||||||
// Child is being set from some value to null
|
|
||||||
|
|
||||||
// remove _adornerLayer and _eatAllHitTestRequests
|
|
||||||
RemoveVisualChild(_adornerLayer); |
|
||||||
RemoveVisualChild(_eatAllHitTestRequests); |
|
||||||
} else if (base.Child == null) { |
|
||||||
// Child is being set from null to some value
|
|
||||||
AddVisualChild(_adornerLayer); |
|
||||||
AddVisualChild(_eatAllHitTestRequests); |
|
||||||
} |
|
||||||
base.Child = value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override Visual GetVisualChild(int index) |
|
||||||
{ |
|
||||||
if (base.Child != null) { |
|
||||||
if (index == 0) |
|
||||||
return base.Child; |
|
||||||
else if (index == 1) |
|
||||||
return _eatAllHitTestRequests; |
|
||||||
else if (index == 2) |
|
||||||
return _adornerLayer; |
|
||||||
} |
|
||||||
return base.GetVisualChild(index); |
|
||||||
} |
|
||||||
|
|
||||||
protected override int VisualChildrenCount { |
|
||||||
get { |
|
||||||
if (base.Child != null) |
|
||||||
return 3; |
|
||||||
else |
|
||||||
return base.VisualChildrenCount; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override Size MeasureOverride(Size constraint) |
|
||||||
{ |
|
||||||
Size result = base.MeasureOverride(constraint); |
|
||||||
if (this.Child != null) { |
|
||||||
_adornerLayer.Measure(constraint); |
|
||||||
_eatAllHitTestRequests.Measure(constraint); |
|
||||||
} |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
protected override Size ArrangeOverride(Size arrangeSize) |
|
||||||
{ |
|
||||||
Size result = base.ArrangeOverride(arrangeSize); |
|
||||||
if (this.Child != null) { |
|
||||||
Rect r = new Rect(new Point(0, 0), arrangeSize); |
|
||||||
_adornerLayer.Arrange(r); |
|
||||||
_eatAllHitTestRequests.Arrange(r); |
|
||||||
} |
|
||||||
return result; |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
protected override void OnQueryCursor(QueryCursorEventArgs e) |
|
||||||
{ |
|
||||||
base.OnQueryCursor(e); |
|
||||||
if (_context != null) { |
|
||||||
Cursor cursor = _context.Services.Tool.CurrentTool.Cursor; |
|
||||||
if (cursor != null) { |
|
||||||
e.Cursor = cursor; |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,15 +0,0 @@ |
|||||||
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.DesignSurface" |
|
||||||
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:Default="clr-namespace:ICSharpCode.WpfDesign.Designer" |
|
||||||
xmlns:Controls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls" |
|
||||||
DataContext="{x:Null}" |
|
||||||
Background="#888"> |
|
||||||
|
|
||||||
<Controls:ZoomControl x:Name="uxZoom"> |
|
||||||
<Default:DesignPanel x:Name="_designPanel"> |
|
||||||
<Border x:Name="_sceneContainer" /> |
|
||||||
</Default:DesignPanel> |
|
||||||
</Controls:ZoomControl> |
|
||||||
|
|
||||||
</UserControl> |
|
||||||
@ -1,258 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Xml; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Xaml; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Services; |
|
||||||
using System.Diagnostics; |
|
||||||
using ICSharpCode.WpfDesign.XamlDom; |
|
||||||
using System.Threading; |
|
||||||
using System.Globalization; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Surface hosting the WPF designer.
|
|
||||||
/// </summary>
|
|
||||||
public partial class DesignSurface |
|
||||||
{ |
|
||||||
static DesignSurface() |
|
||||||
{ |
|
||||||
//TODO: this is for converters (see PropertyGrid)
|
|
||||||
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; |
|
||||||
} |
|
||||||
|
|
||||||
public DesignSurface() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
|
|
||||||
this.AddCommandHandler(ApplicationCommands.Undo, Undo, CanUndo); |
|
||||||
this.AddCommandHandler(ApplicationCommands.Redo, Redo, CanRedo); |
|
||||||
this.AddCommandHandler(ApplicationCommands.Copy, Copy, HasSelection); |
|
||||||
this.AddCommandHandler(ApplicationCommands.Cut, Cut, HasSelection); |
|
||||||
this.AddCommandHandler(ApplicationCommands.Delete, Delete, CanDelete); |
|
||||||
this.AddCommandHandler(ApplicationCommands.Paste, Paste, CanPaste); |
|
||||||
this.AddCommandHandler(ApplicationCommands.SelectAll, SelectAll, CanSelectAll); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
if (e.OriginalSource == uxZoom.ScrollViewer) { |
|
||||||
UnselectAll(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
DesignContext _designContext; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the active design context.
|
|
||||||
/// </summary>
|
|
||||||
public DesignContext DesignContext { |
|
||||||
get { return _designContext; } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes the designer content from the specified XmlReader.
|
|
||||||
/// </summary>
|
|
||||||
public void LoadDesigner(XmlReader xamlReader, XamlLoadSettings loadSettings) |
|
||||||
{ |
|
||||||
UnloadDesigner(); |
|
||||||
loadSettings = loadSettings ?? new XamlLoadSettings(); |
|
||||||
loadSettings.CustomServiceRegisterFunctions.Add( |
|
||||||
context => context.Services.AddService(typeof(IDesignPanel), _designPanel)); |
|
||||||
InitializeDesigner(new XamlDesignContext(xamlReader, loadSettings)); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves the designer content into the specified XmlWriter.
|
|
||||||
/// </summary>
|
|
||||||
public void SaveDesigner(XmlWriter writer) |
|
||||||
{ |
|
||||||
_designContext.Save(writer); |
|
||||||
} |
|
||||||
|
|
||||||
void InitializeDesigner(DesignContext context) |
|
||||||
{ |
|
||||||
_designContext = context; |
|
||||||
_designPanel.Context = context; |
|
||||||
|
|
||||||
if (context.RootItem != null) { |
|
||||||
_sceneContainer.Child = context.RootItem.View; |
|
||||||
} |
|
||||||
|
|
||||||
context.Services.RunWhenAvailable<UndoService>( |
|
||||||
undoService => undoService.UndoStackChanged += delegate { |
|
||||||
CommandManager.InvalidateRequerySuggested(); |
|
||||||
} |
|
||||||
); |
|
||||||
context.Services.Selection.SelectionChanged += delegate { |
|
||||||
CommandManager.InvalidateRequerySuggested(); |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unloads the designer content.
|
|
||||||
/// </summary>
|
|
||||||
public void UnloadDesigner() |
|
||||||
{ |
|
||||||
if (_designContext != null) { |
|
||||||
foreach (object o in _designContext.Services.AllServices) { |
|
||||||
IDisposable d = o as IDisposable; |
|
||||||
if (d != null) d.Dispose(); |
|
||||||
} |
|
||||||
} |
|
||||||
_designContext = null; |
|
||||||
_designPanel.Context = null; |
|
||||||
_sceneContainer.Child = null; |
|
||||||
_designPanel.Adorners.Clear(); |
|
||||||
} |
|
||||||
|
|
||||||
#region Commands
|
|
||||||
|
|
||||||
public bool CanUndo() |
|
||||||
{ |
|
||||||
UndoService undoService = GetService<UndoService>(); |
|
||||||
return undoService != null && undoService.CanUndo; |
|
||||||
} |
|
||||||
|
|
||||||
public void Undo() |
|
||||||
{ |
|
||||||
UndoService undoService = GetService<UndoService>(); |
|
||||||
IUndoAction action = undoService.UndoActions.First(); |
|
||||||
Debug.WriteLine("Undo " + action.Title); |
|
||||||
undoService.Undo(); |
|
||||||
_designContext.Services.Selection.SetSelectedComponents(GetLiveElements(action.AffectedElements)); |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanRedo() |
|
||||||
{ |
|
||||||
UndoService undoService = GetService<UndoService>(); |
|
||||||
return undoService != null && undoService.CanRedo; |
|
||||||
} |
|
||||||
|
|
||||||
public void Redo() |
|
||||||
{ |
|
||||||
UndoService undoService = GetService<UndoService>(); |
|
||||||
IUndoAction action = undoService.RedoActions.First(); |
|
||||||
Debug.WriteLine("Redo " + action.Title); |
|
||||||
undoService.Redo(); |
|
||||||
_designContext.Services.Selection.SetSelectedComponents(GetLiveElements(action.AffectedElements)); |
|
||||||
} |
|
||||||
|
|
||||||
public bool HasSelection() |
|
||||||
{ |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
public void Copy() |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public void Cut() |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanDelete() |
|
||||||
{ |
|
||||||
if (_designContext != null) { |
|
||||||
return ModelTools.CanDeleteComponents(_designContext.Services.Selection.SelectedItems); |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
public void Delete() |
|
||||||
{ |
|
||||||
if (_designContext != null) { |
|
||||||
ModelTools.DeleteComponents(_designContext.Services.Selection.SelectedItems); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanPaste() |
|
||||||
{ |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
public void Paste() |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanSelectAll() |
|
||||||
{ |
|
||||||
return DesignContext != null; |
|
||||||
} |
|
||||||
|
|
||||||
//TODO: Do not select layout root
|
|
||||||
public void SelectAll() |
|
||||||
{ |
|
||||||
var items = Descendants(DesignContext.RootItem).Where(item => ModelTools.CanSelectComponent(item)).ToArray(); |
|
||||||
DesignContext.Services.Selection.SetSelectedComponents(items); |
|
||||||
} |
|
||||||
|
|
||||||
public void UnselectAll() |
|
||||||
{ |
|
||||||
DesignContext.Services.Selection.SetSelectedComponents(null); |
|
||||||
} |
|
||||||
|
|
||||||
//TODO: Share with Outline / PlacementBehavior
|
|
||||||
public static IEnumerable<DesignItem> DescendantsAndSelf(DesignItem item) |
|
||||||
{ |
|
||||||
yield return item; |
|
||||||
foreach (var child in Descendants(item)) { |
|
||||||
yield return child; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static IEnumerable<DesignItem> Descendants(DesignItem item) |
|
||||||
{ |
|
||||||
if (item.ContentPropertyName != null) { |
|
||||||
var content = item.ContentProperty; |
|
||||||
if (content.IsCollection) { |
|
||||||
foreach (var child in content.CollectionElements) { |
|
||||||
foreach (var child2 in DescendantsAndSelf(child)) { |
|
||||||
yield return child2; |
|
||||||
} |
|
||||||
} |
|
||||||
} else { |
|
||||||
if (content.Value != null) { |
|
||||||
foreach (var child2 in DescendantsAndSelf(content.Value)) { |
|
||||||
yield return child2; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// Filters an element list, dropping all elements that are not part of the xaml document
|
|
||||||
// (e.g. because they were deleted).
|
|
||||||
static List<DesignItem> GetLiveElements(ICollection<DesignItem> items) |
|
||||||
{ |
|
||||||
List<DesignItem> result = new List<DesignItem>(items.Count); |
|
||||||
foreach (DesignItem item in items) { |
|
||||||
if (ModelTools.IsInDocument(item) && ModelTools.CanSelectComponent(item)) { |
|
||||||
result.Add(item); |
|
||||||
} |
|
||||||
} |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
T GetService<T>() where T : class |
|
||||||
{ |
|
||||||
if (_designContext != null) |
|
||||||
return _designContext.Services.GetService<T>(); |
|
||||||
else |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
#endregion
|
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,24 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <author name="Daniel Grunwald"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// When the designer is hosted in a Windows.Forms application, exceptions in
|
|
||||||
/// drag'n'drop handlers are silently ignored.
|
|
||||||
/// Applications hosting the designer should specify a delegate to their own exception handling
|
|
||||||
/// method. The default is Environment.FailFast.
|
|
||||||
/// </summary>
|
|
||||||
public static class DragDropExceptionHandler |
|
||||||
{ |
|
||||||
public static Action<Exception> HandleException = delegate(Exception ex) { |
|
||||||
Environment.FailFast(ex.ToString()); |
|
||||||
}; |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,86 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Reflection; |
|
||||||
using System.Collections; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Input; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer |
|
||||||
{ |
|
||||||
public static class ExtensionMethods |
|
||||||
{ |
|
||||||
public static double Coerce(this double d, double min, double max) |
|
||||||
{ |
|
||||||
return Math.Max(Math.Min(d, max), min); |
|
||||||
} |
|
||||||
|
|
||||||
public static void AddRange<T>(this ICollection<T> col, IEnumerable<T> items) |
|
||||||
{ |
|
||||||
foreach (var item in items) { |
|
||||||
col.Add(item); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static object GetDataContext(this RoutedEventArgs e) |
|
||||||
{ |
|
||||||
var f = e.OriginalSource as FrameworkElement; |
|
||||||
if (f != null) { |
|
||||||
return f.DataContext; |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
public static T FindAncestor<T>(this DependencyObject d, string name) where T : class |
|
||||||
{ |
|
||||||
while (true) { |
|
||||||
if (d == null) return null; |
|
||||||
if (d is T && d is FrameworkElement && (d as FrameworkElement).Name == name) return d as T; |
|
||||||
d = VisualTreeHelper.GetParent(d); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static T FindAncestor<T>(this DependencyObject d) where T : class |
|
||||||
{ |
|
||||||
while (true) { |
|
||||||
if (d == null) return null; |
|
||||||
if (d is T) return d as T; |
|
||||||
d = VisualTreeHelper.GetParent(d); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static T FindChild<T>(this DependencyObject d) where T : class |
|
||||||
{ |
|
||||||
if (d is T) return d as T; |
|
||||||
int n = VisualTreeHelper.GetChildrenCount(d); |
|
||||||
for (int i = 0; i < n; i++) { |
|
||||||
var child = VisualTreeHelper.GetChild(d, i); |
|
||||||
var result = FindChild<T>(child); |
|
||||||
if (result != null) return result; |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
public static void AddCommandHandler(this UIElement element, ICommand command, Action execute) |
|
||||||
{ |
|
||||||
AddCommandHandler(element, command, execute, null); |
|
||||||
} |
|
||||||
|
|
||||||
public static void AddCommandHandler(this UIElement element, ICommand command, Action execute, Func<bool> canExecute) |
|
||||||
{ |
|
||||||
var cb = new CommandBinding(command); |
|
||||||
if (canExecute != null) { |
|
||||||
cb.CanExecute += delegate(object sender, CanExecuteRoutedEventArgs e) { |
|
||||||
e.CanExecute = canExecute(); |
|
||||||
e.Handled = true; |
|
||||||
}; |
|
||||||
} |
|
||||||
cb.Executed += delegate(object sender, ExecutedRoutedEventArgs e) { |
|
||||||
execute(); |
|
||||||
}; |
|
||||||
element.CommandBindings.Add(cb); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,31 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Controls; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
[ExtensionFor(typeof(Panel))] |
|
||||||
public class BorderForInvisibleControl : PermanentAdornerProvider |
|
||||||
{ |
|
||||||
protected override void OnInitialized() |
|
||||||
{ |
|
||||||
base.OnInitialized(); |
|
||||||
|
|
||||||
var adornerPanel = new AdornerPanel(); |
|
||||||
var border = new Border(); |
|
||||||
border.BorderThickness = new Thickness(1); |
|
||||||
border.BorderBrush = Brushes.WhiteSmoke; |
|
||||||
border.IsHitTestVisible = false; |
|
||||||
AdornerPanel.SetPlacement(border, AdornerPlacement.FillContent); |
|
||||||
adornerPanel.Children.Add(border); |
|
||||||
Adorners.Add(adornerPanel); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,84 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
|
|
||||||
using ICSharpCode.WpfDesign.Designer.Controls; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Provides <see cref="IPlacementBehavior"/> behavior for <see cref="Canvas"/>.
|
|
||||||
/// </summary>
|
|
||||||
[ExtensionFor(typeof(Canvas), OverrideExtension=typeof(DefaultPlacementBehavior))] |
|
||||||
public sealed class CanvasPlacementSupport : SnaplinePlacementBehavior |
|
||||||
{ |
|
||||||
static double GetLeft(UIElement element) |
|
||||||
{ |
|
||||||
double v = (double)element.GetValue(Canvas.LeftProperty); |
|
||||||
if (double.IsNaN(v)) |
|
||||||
return 0; |
|
||||||
else |
|
||||||
return v; |
|
||||||
} |
|
||||||
|
|
||||||
static double GetTop(UIElement element) |
|
||||||
{ |
|
||||||
double v = (double)element.GetValue(Canvas.TopProperty); |
|
||||||
if (double.IsNaN(v)) |
|
||||||
return 0; |
|
||||||
else |
|
||||||
return v; |
|
||||||
} |
|
||||||
|
|
||||||
//TODO: Is default way ok?
|
|
||||||
//public override Rect GetPosition(PlacementOperation operation, DesignItem childItem)
|
|
||||||
//{
|
|
||||||
// UIElement child = childItem.View;
|
|
||||||
// return new Rect(GetLeft(child), GetTop(child), ModelTools.GetWidth(child), ModelTools.GetHeight(child));
|
|
||||||
//}
|
|
||||||
|
|
||||||
public override void SetPosition(PlacementInformation info) |
|
||||||
{ |
|
||||||
base.SetPosition(info); |
|
||||||
info.Item.Properties[FrameworkElement.MarginProperty].Reset(); |
|
||||||
|
|
||||||
UIElement child = info.Item.View; |
|
||||||
Rect newPosition = info.Bounds; |
|
||||||
|
|
||||||
if (newPosition.Left != GetLeft(child)) { |
|
||||||
info.Item.Properties.GetAttachedProperty(Canvas.LeftProperty).SetValue(newPosition.Left); |
|
||||||
} |
|
||||||
if (newPosition.Top != GetTop(child)) { |
|
||||||
info.Item.Properties.GetAttachedProperty(Canvas.TopProperty).SetValue(newPosition.Top); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override void LeaveContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
base.LeaveContainer(operation); |
|
||||||
foreach (PlacementInformation info in operation.PlacedItems) { |
|
||||||
info.Item.Properties.GetAttachedProperty(Canvas.LeftProperty).Reset(); |
|
||||||
info.Item.Properties.GetAttachedProperty(Canvas.TopProperty).Reset(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override void EnterContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
base.EnterContainer(operation); |
|
||||||
foreach (PlacementInformation info in operation.PlacedItems) { |
|
||||||
info.Item.Properties[FrameworkElement.HorizontalAlignmentProperty].Reset(); |
|
||||||
info.Item.Properties[FrameworkElement.VerticalAlignmentProperty].Reset(); |
|
||||||
info.Item.Properties[FrameworkElement.MarginProperty].Reset(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,96 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Controls; |
|
||||||
using System.Diagnostics; |
|
||||||
using ICSharpCode.WpfDesign.XamlDom; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
[ExtensionFor(typeof(UIElement))] |
|
||||||
public class DefaultPlacementBehavior : BehaviorExtension, IPlacementBehavior |
|
||||||
{ |
|
||||||
protected override void OnInitialized() |
|
||||||
{ |
|
||||||
base.OnInitialized(); |
|
||||||
if (ExtendedItem.ContentProperty == null || |
|
||||||
Metadata.IsPlacementDisabled(ExtendedItem.ComponentType)) |
|
||||||
return; |
|
||||||
ExtendedItem.AddBehavior(typeof(IPlacementBehavior), this); |
|
||||||
} |
|
||||||
|
|
||||||
public virtual bool CanPlace(ICollection<DesignItem> childItems, PlacementType type, PlacementAlignment position) |
|
||||||
{ |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
public virtual void BeginPlacement(PlacementOperation operation) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public virtual void EndPlacement(PlacementOperation operation) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public virtual Rect GetPosition(PlacementOperation operation, DesignItem item) |
|
||||||
{ |
|
||||||
var p = item.View.TranslatePoint(new Point(), operation.CurrentContainer.View); |
|
||||||
return new Rect(p, item.View.RenderSize); |
|
||||||
} |
|
||||||
|
|
||||||
public virtual void BeforeSetPosition(PlacementOperation operation) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public virtual void SetPosition(PlacementInformation info) |
|
||||||
{ |
|
||||||
ModelTools.Resize(info.Item, info.Bounds.Width, info.Bounds.Height); |
|
||||||
} |
|
||||||
|
|
||||||
public virtual bool CanLeaveContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
public virtual void LeaveContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
if (ExtendedItem.ContentProperty.IsCollection) { |
|
||||||
foreach (var info in operation.PlacedItems) { |
|
||||||
ExtendedItem.ContentProperty.CollectionElements.Remove(info.Item); |
|
||||||
} |
|
||||||
} else { |
|
||||||
ExtendedItem.ContentProperty.Reset(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public virtual bool CanEnterContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
if (ExtendedItem.ContentProperty.IsCollection && |
|
||||||
CollectionSupport.CanCollectionAdd(ExtendedItem.ContentProperty.ReturnType, |
|
||||||
operation.PlacedItems.Select(p => p.Item.Component))) |
|
||||||
return true; |
|
||||||
return !ExtendedItem.ContentProperty.IsSet; |
|
||||||
} |
|
||||||
|
|
||||||
public virtual void EnterContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
if (ExtendedItem.ContentProperty.IsCollection) { |
|
||||||
foreach (var info in operation.PlacedItems) { |
|
||||||
ExtendedItem.ContentProperty.CollectionElements.Add(info.Item); |
|
||||||
} |
|
||||||
} else { |
|
||||||
ExtendedItem.ContentProperty.SetValue(operation.PlacedItems[0].Item); |
|
||||||
} |
|
||||||
if (operation.Type == PlacementType.AddItem) { |
|
||||||
foreach (var info in operation.PlacedItems) { |
|
||||||
SetPosition(info); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,136 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Threading; |
|
||||||
|
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Controls; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Allows arranging the rows/column on a grid.
|
|
||||||
/// </summary>
|
|
||||||
[ExtensionFor(typeof(Grid))] |
|
||||||
[ExtensionServer(typeof(LogicalOrExtensionServer<PrimarySelectionExtensionServer, PrimarySelectionParentExtensionServer>))] |
|
||||||
public class GridAdornerProvider : AdornerProvider |
|
||||||
{ |
|
||||||
sealed class RowSplitterPlacement : AdornerPlacement |
|
||||||
{ |
|
||||||
readonly RowDefinition row; |
|
||||||
public RowSplitterPlacement(RowDefinition row) { this.row = row; } |
|
||||||
|
|
||||||
public override void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize) |
|
||||||
{ |
|
||||||
adorner.Arrange(new Rect(-(GridRailAdorner.RailSize + GridRailAdorner.RailDistance), |
|
||||||
row.Offset - GridRailAdorner.SplitterWidth / 2, |
|
||||||
GridRailAdorner.RailSize + GridRailAdorner.RailDistance + adornedElementSize.Width, |
|
||||||
GridRailAdorner.SplitterWidth)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class ColumnSplitterPlacement : AdornerPlacement |
|
||||||
{ |
|
||||||
readonly ColumnDefinition column; |
|
||||||
public ColumnSplitterPlacement(ColumnDefinition column) { this.column = column; } |
|
||||||
|
|
||||||
public override void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize) |
|
||||||
{ |
|
||||||
adorner.Arrange(new Rect(column.Offset - GridRailAdorner.SplitterWidth / 2, |
|
||||||
-(GridRailAdorner.RailSize + GridRailAdorner.RailDistance), |
|
||||||
GridRailAdorner.SplitterWidth, |
|
||||||
GridRailAdorner.RailSize + GridRailAdorner.RailDistance + adornedElementSize.Height)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
AdornerPanel adornerPanel = new AdornerPanel(); |
|
||||||
GridRailAdorner topBar, leftBar; |
|
||||||
|
|
||||||
protected override void OnInitialized() |
|
||||||
{ |
|
||||||
leftBar = new GridRailAdorner(this.ExtendedItem, adornerPanel, Orientation.Vertical); |
|
||||||
topBar = new GridRailAdorner(this.ExtendedItem, adornerPanel, Orientation.Horizontal); |
|
||||||
|
|
||||||
RelativePlacement rp = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Stretch); |
|
||||||
rp.XOffset -= GridRailAdorner.RailDistance; |
|
||||||
AdornerPanel.SetPlacement(leftBar, rp); |
|
||||||
rp = new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Top); |
|
||||||
rp.YOffset -= GridRailAdorner.RailDistance; |
|
||||||
AdornerPanel.SetPlacement(topBar, rp); |
|
||||||
|
|
||||||
adornerPanel.Children.Add(leftBar); |
|
||||||
adornerPanel.Children.Add(topBar); |
|
||||||
this.Adorners.Add(adornerPanel); |
|
||||||
|
|
||||||
CreateSplitter(); |
|
||||||
this.ExtendedItem.PropertyChanged += OnPropertyChanged; |
|
||||||
|
|
||||||
base.OnInitialized(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnRemove() |
|
||||||
{ |
|
||||||
this.ExtendedItem.PropertyChanged -= OnPropertyChanged; |
|
||||||
base.OnRemove(); |
|
||||||
} |
|
||||||
|
|
||||||
void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
if (e.PropertyName == "RowDefinitions" || e.PropertyName == "ColumnDefinitions") { |
|
||||||
CreateSplitter(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
readonly List<GridSplitterAdorner> splitterList = new List<GridSplitterAdorner>(); |
|
||||||
/// <summary>
|
|
||||||
/// flag used to ensure that the asynchronus splitter creation is only enqueued once
|
|
||||||
/// </summary>
|
|
||||||
bool requireSplitterRecreation; |
|
||||||
|
|
||||||
void CreateSplitter() |
|
||||||
{ |
|
||||||
if (requireSplitterRecreation) return; |
|
||||||
requireSplitterRecreation = true; |
|
||||||
|
|
||||||
// splitter creation is delayed to prevent unnecessary splitter re-creation when multiple
|
|
||||||
// changes to the collection are done.
|
|
||||||
// It also ensures that the Offset property of new rows/columns is initialized when the splitter
|
|
||||||
// is added.
|
|
||||||
Dispatcher.CurrentDispatcher.BeginInvoke( |
|
||||||
DispatcherPriority.Loaded, // Loaded = after layout, but before input
|
|
||||||
(Action)delegate { |
|
||||||
requireSplitterRecreation = false; |
|
||||||
foreach (GridSplitterAdorner splitter in splitterList) { |
|
||||||
adornerPanel.Children.Remove(splitter); |
|
||||||
} |
|
||||||
splitterList.Clear(); |
|
||||||
Grid grid = (Grid)this.ExtendedItem.Component; |
|
||||||
IList<DesignItem> col = this.ExtendedItem.Properties["RowDefinitions"].CollectionElements; |
|
||||||
for (int i = 1; i < grid.RowDefinitions.Count; i++) { |
|
||||||
RowDefinition row = grid.RowDefinitions[i]; |
|
||||||
GridRowSplitterAdorner splitter = new GridRowSplitterAdorner(this.ExtendedItem, col[i-1], col[i]); |
|
||||||
AdornerPanel.SetPlacement(splitter, new RowSplitterPlacement(row)); |
|
||||||
adornerPanel.Children.Add(splitter); |
|
||||||
splitterList.Add(splitter); |
|
||||||
} |
|
||||||
col = this.ExtendedItem.Properties["ColumnDefinitions"].CollectionElements; |
|
||||||
for (int i = 1; i < grid.ColumnDefinitions.Count; i++) { |
|
||||||
ColumnDefinition column = grid.ColumnDefinitions[i]; |
|
||||||
GridColumnSplitterAdorner splitter = new GridColumnSplitterAdorner(this.ExtendedItem, col[i-1], col[i]); |
|
||||||
AdornerPanel.SetPlacement(splitter, new ColumnSplitterPlacement(column)); |
|
||||||
adornerPanel.Children.Add(splitter); |
|
||||||
splitterList.Add(splitter); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,292 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Windows; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Controls; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Provides <see cref="IPlacementBehavior"/> behavior for <see cref="Grid"/>.
|
|
||||||
/// </summary>
|
|
||||||
[ExtensionFor(typeof(Grid), OverrideExtension=typeof(DefaultPlacementBehavior))] |
|
||||||
public sealed class GridPlacementSupport : SnaplinePlacementBehavior |
|
||||||
{ |
|
||||||
Grid grid; |
|
||||||
|
|
||||||
protected override void OnInitialized() |
|
||||||
{ |
|
||||||
base.OnInitialized(); |
|
||||||
grid = (Grid)this.ExtendedItem.Component; |
|
||||||
} |
|
||||||
|
|
||||||
//TODO: Is default way ok?
|
|
||||||
//public override Rect GetPosition(PlacementOperation operation, DesignItem child)
|
|
||||||
//{
|
|
||||||
// FrameworkElement obj = child.Component as FrameworkElement;
|
|
||||||
// if (obj == null) return new Rect();
|
|
||||||
|
|
||||||
// Thickness margin = obj.Margin;
|
|
||||||
|
|
||||||
// double left, width, right;
|
|
||||||
// switch (obj.HorizontalAlignment) {
|
|
||||||
// case HorizontalAlignment.Stretch:
|
|
||||||
// left = GetColumnOffset(Grid.GetColumn(obj)) + margin.Left;
|
|
||||||
// right = GetColumnOffset(Grid.GetColumn(obj) + Grid.GetColumnSpan(obj)) - margin.Right;
|
|
||||||
// width = right - left;
|
|
||||||
// break;
|
|
||||||
// case HorizontalAlignment.Left:
|
|
||||||
// left = GetColumnOffset(Grid.GetColumn(obj)) + margin.Left;
|
|
||||||
// width = ModelTools.GetWidth(obj);
|
|
||||||
// right = left + width;
|
|
||||||
// break;
|
|
||||||
// case HorizontalAlignment.Right:
|
|
||||||
// right = GetColumnOffset(Grid.GetColumn(obj) + Grid.GetColumnSpan(obj)) - margin.Right;
|
|
||||||
// width = ModelTools.GetWidth(obj);
|
|
||||||
// left = right - width;
|
|
||||||
// break;
|
|
||||||
// case HorizontalAlignment.Center:
|
|
||||||
// throw new NotImplementedException();
|
|
||||||
// default:
|
|
||||||
// throw new NotSupportedException();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// double top, height, bottom;
|
|
||||||
// switch (obj.VerticalAlignment) {
|
|
||||||
// case VerticalAlignment.Stretch:
|
|
||||||
// top = GetRowOffset(Grid.GetRow(obj)) + margin.Top;
|
|
||||||
// bottom = GetRowOffset(Grid.GetRow(obj) + Grid.GetRowSpan(obj)) - margin.Bottom;
|
|
||||||
// height = bottom - top;
|
|
||||||
// break;
|
|
||||||
// case VerticalAlignment.Top:
|
|
||||||
// top = GetRowOffset(Grid.GetRow(obj)) + margin.Top;
|
|
||||||
// height = ModelTools.GetHeight(obj);
|
|
||||||
// bottom = top + height;
|
|
||||||
// break;
|
|
||||||
// case VerticalAlignment.Bottom:
|
|
||||||
// bottom = GetRowOffset(Grid.GetRow(obj) + Grid.GetRowSpan(obj)) - margin.Bottom;
|
|
||||||
// height = ModelTools.GetHeight(obj);
|
|
||||||
// top = bottom - height;
|
|
||||||
// break;
|
|
||||||
// case VerticalAlignment.Center:
|
|
||||||
// throw new NotImplementedException();
|
|
||||||
// default:
|
|
||||||
// throw new NotSupportedException();
|
|
||||||
// }
|
|
||||||
// return new Rect(left, top, Math.Max(0, width), Math.Max(0, height));
|
|
||||||
//}
|
|
||||||
|
|
||||||
double GetColumnOffset(int index) |
|
||||||
{ |
|
||||||
// when the grid has no columns, we still need to return 0 for index=0 and grid.Width for index=1
|
|
||||||
if (index == 0) |
|
||||||
return 0; |
|
||||||
else if (index < grid.ColumnDefinitions.Count) |
|
||||||
return grid.ColumnDefinitions[index].Offset; |
|
||||||
else |
|
||||||
return grid.ActualWidth; |
|
||||||
} |
|
||||||
|
|
||||||
double GetRowOffset(int index) |
|
||||||
{ |
|
||||||
if (index == 0) |
|
||||||
return 0; |
|
||||||
else if (index < grid.RowDefinitions.Count) |
|
||||||
return grid.RowDefinitions[index].Offset; |
|
||||||
else |
|
||||||
return grid.ActualHeight; |
|
||||||
} |
|
||||||
|
|
||||||
const double epsilon = 0.00000001; |
|
||||||
|
|
||||||
int GetColumnIndex(double x) |
|
||||||
{ |
|
||||||
if (grid.ColumnDefinitions.Count == 0) |
|
||||||
return 0; |
|
||||||
for (int i = 1; i < grid.ColumnDefinitions.Count; i++) { |
|
||||||
if (x < grid.ColumnDefinitions[i].Offset - epsilon) |
|
||||||
return i - 1; |
|
||||||
} |
|
||||||
return grid.ColumnDefinitions.Count - 1; |
|
||||||
} |
|
||||||
|
|
||||||
int GetRowIndex(double y) |
|
||||||
{ |
|
||||||
if (grid.RowDefinitions.Count == 0) |
|
||||||
return 0; |
|
||||||
for (int i = 1; i < grid.RowDefinitions.Count; i++) { |
|
||||||
if (y < grid.RowDefinitions[i].Offset - epsilon) |
|
||||||
return i - 1; |
|
||||||
} |
|
||||||
return grid.RowDefinitions.Count - 1; |
|
||||||
} |
|
||||||
|
|
||||||
int GetEndColumnIndex(double x) |
|
||||||
{ |
|
||||||
if (grid.ColumnDefinitions.Count == 0) |
|
||||||
return 0; |
|
||||||
for (int i = 1; i < grid.ColumnDefinitions.Count; i++) { |
|
||||||
if (x <= grid.ColumnDefinitions[i].Offset + epsilon) |
|
||||||
return i - 1; |
|
||||||
} |
|
||||||
return grid.ColumnDefinitions.Count - 1; |
|
||||||
} |
|
||||||
|
|
||||||
int GetEndRowIndex(double y) |
|
||||||
{ |
|
||||||
if (grid.RowDefinitions.Count == 0) |
|
||||||
return 0; |
|
||||||
for (int i = 1; i < grid.RowDefinitions.Count; i++) { |
|
||||||
if (y <= grid.RowDefinitions[i].Offset + epsilon) |
|
||||||
return i - 1; |
|
||||||
} |
|
||||||
return grid.RowDefinitions.Count - 1; |
|
||||||
} |
|
||||||
|
|
||||||
static void SetColumn(DesignItem item, int column, int columnSpan) |
|
||||||
{ |
|
||||||
Debug.Assert(item != null && column >= 0 && columnSpan > 0); |
|
||||||
item.Properties.GetAttachedProperty(Grid.ColumnProperty).SetValue(column); |
|
||||||
if (columnSpan == 1) { |
|
||||||
item.Properties.GetAttachedProperty(Grid.ColumnSpanProperty).Reset(); |
|
||||||
} else { |
|
||||||
item.Properties.GetAttachedProperty(Grid.ColumnSpanProperty).SetValue(columnSpan); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void SetRow(DesignItem item, int row, int rowSpan) |
|
||||||
{ |
|
||||||
Debug.Assert(item != null && row >= 0 && rowSpan > 0); |
|
||||||
item.Properties.GetAttachedProperty(Grid.RowProperty).SetValue(row); |
|
||||||
if (rowSpan == 1) { |
|
||||||
item.Properties.GetAttachedProperty(Grid.RowSpanProperty).Reset(); |
|
||||||
} else { |
|
||||||
item.Properties.GetAttachedProperty(Grid.RowSpanProperty).SetValue(rowSpan); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static HorizontalAlignment SuggestHorizontalAlignment(Rect itemBounds, Rect availableSpaceRect) |
|
||||||
{ |
|
||||||
if (itemBounds.Right < (availableSpaceRect.Left + availableSpaceRect.Right) / 2) { |
|
||||||
return HorizontalAlignment.Left; |
|
||||||
} else if (itemBounds.Left > (availableSpaceRect.Left + availableSpaceRect.Right) / 2) { |
|
||||||
return HorizontalAlignment.Right; |
|
||||||
} else { |
|
||||||
return HorizontalAlignment.Stretch; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static VerticalAlignment SuggestVerticalAlignment(Rect itemBounds, Rect availableSpaceRect) |
|
||||||
{ |
|
||||||
if (itemBounds.Bottom < (availableSpaceRect.Top + availableSpaceRect.Bottom) / 2) { |
|
||||||
return VerticalAlignment.Top; |
|
||||||
} else if (itemBounds.Top > (availableSpaceRect.Top + availableSpaceRect.Bottom) / 2) { |
|
||||||
return VerticalAlignment.Bottom; |
|
||||||
} else { |
|
||||||
return VerticalAlignment.Stretch; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
GrayOutDesignerExceptActiveArea grayOut; |
|
||||||
|
|
||||||
public override void EndPlacement(PlacementOperation operation) |
|
||||||
{ |
|
||||||
GrayOutDesignerExceptActiveArea.Stop(ref grayOut); |
|
||||||
base.EndPlacement(operation); |
|
||||||
} |
|
||||||
|
|
||||||
public override void SetPosition(PlacementInformation info) |
|
||||||
{ |
|
||||||
base.SetPosition(info); |
|
||||||
if (info.Operation.Type == PlacementType.AddItem) { |
|
||||||
SetColumn(info.Item, GetColumnIndex(info.Bounds.Left), 1); |
|
||||||
SetRow(info.Item, GetRowIndex(info.Bounds.Top), 1); |
|
||||||
} else { |
|
||||||
int leftColumnIndex = GetColumnIndex(info.Bounds.Left); |
|
||||||
int rightColumnIndex = GetEndColumnIndex(info.Bounds.Right); |
|
||||||
if (rightColumnIndex < leftColumnIndex) rightColumnIndex = leftColumnIndex; |
|
||||||
SetColumn(info.Item, leftColumnIndex, rightColumnIndex - leftColumnIndex + 1); |
|
||||||
int topRowIndex = GetRowIndex(info.Bounds.Top); |
|
||||||
int bottomRowIndex = GetEndRowIndex(info.Bounds.Bottom); |
|
||||||
if (bottomRowIndex < topRowIndex) bottomRowIndex = topRowIndex; |
|
||||||
SetRow(info.Item, topRowIndex, bottomRowIndex - topRowIndex + 1); |
|
||||||
|
|
||||||
Rect availableSpaceRect = new Rect( |
|
||||||
new Point(GetColumnOffset(leftColumnIndex), GetRowOffset(topRowIndex)), |
|
||||||
new Point(GetColumnOffset(rightColumnIndex + 1), GetRowOffset(bottomRowIndex + 1)) |
|
||||||
); |
|
||||||
if (grayOut != null) { |
|
||||||
grayOut.AnimateActiveAreaRectTo(availableSpaceRect); |
|
||||||
} else { |
|
||||||
GrayOutDesignerExceptActiveArea.Start(ref grayOut, this.Services, this.ExtendedItem.View, availableSpaceRect); |
|
||||||
} |
|
||||||
|
|
||||||
HorizontalAlignment ha = (HorizontalAlignment)info.Item.Properties[FrameworkElement.HorizontalAlignmentProperty].ValueOnInstance; |
|
||||||
VerticalAlignment va = (VerticalAlignment)info.Item.Properties[FrameworkElement.VerticalAlignmentProperty].ValueOnInstance; |
|
||||||
ha = SuggestHorizontalAlignment(info.Bounds, availableSpaceRect); |
|
||||||
va = SuggestVerticalAlignment(info.Bounds, availableSpaceRect); |
|
||||||
|
|
||||||
info.Item.Properties[FrameworkElement.HorizontalAlignmentProperty].SetValue(ha); |
|
||||||
info.Item.Properties[FrameworkElement.VerticalAlignmentProperty].SetValue(va); |
|
||||||
|
|
||||||
Thickness margin = new Thickness(0, 0, 0, 0); |
|
||||||
if (ha == HorizontalAlignment.Left || ha == HorizontalAlignment.Stretch) |
|
||||||
margin.Left = info.Bounds.Left - GetColumnOffset(leftColumnIndex); |
|
||||||
if (va == VerticalAlignment.Top || va == VerticalAlignment.Stretch) |
|
||||||
margin.Top = info.Bounds.Top - GetRowOffset(topRowIndex); |
|
||||||
if (ha == HorizontalAlignment.Right || ha == HorizontalAlignment.Stretch) |
|
||||||
margin.Right = GetColumnOffset(rightColumnIndex + 1) - info.Bounds.Right; |
|
||||||
if (va == VerticalAlignment.Bottom || va == VerticalAlignment.Stretch) |
|
||||||
margin.Bottom = GetRowOffset(bottomRowIndex + 1) - info.Bounds.Bottom; |
|
||||||
info.Item.Properties[FrameworkElement.MarginProperty].SetValue(margin); |
|
||||||
|
|
||||||
if (ha == HorizontalAlignment.Stretch) |
|
||||||
info.Item.Properties[FrameworkElement.WidthProperty].Reset(); |
|
||||||
else |
|
||||||
info.Item.Properties[FrameworkElement.WidthProperty].SetValue(info.Bounds.Width); |
|
||||||
if (va == VerticalAlignment.Stretch) |
|
||||||
info.Item.Properties[FrameworkElement.HeightProperty].Reset(); |
|
||||||
else |
|
||||||
info.Item.Properties[FrameworkElement.HeightProperty].SetValue(info.Bounds.Height); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override void LeaveContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
base.LeaveContainer(operation); |
|
||||||
foreach (PlacementInformation info in operation.PlacedItems) { |
|
||||||
if (info.Item.ComponentType == typeof(ColumnDefinition)) { |
|
||||||
// TODO: combine the width of the deleted column with the previous column
|
|
||||||
this.ExtendedItem.Properties["ColumnDefinitions"].CollectionElements.Remove(info.Item); |
|
||||||
} else if (info.Item.ComponentType == typeof(RowDefinition)) { |
|
||||||
this.ExtendedItem.Properties["RowDefinitions"].CollectionElements.Remove(info.Item); |
|
||||||
} else { |
|
||||||
info.Item.Properties.GetAttachedProperty(Grid.RowProperty).Reset(); |
|
||||||
info.Item.Properties.GetAttachedProperty(Grid.ColumnProperty).Reset(); |
|
||||||
info.Item.Properties.GetAttachedProperty(Grid.RowSpanProperty).Reset(); |
|
||||||
info.Item.Properties.GetAttachedProperty(Grid.ColumnSpanProperty).Reset(); |
|
||||||
|
|
||||||
HorizontalAlignment ha = (HorizontalAlignment)info.Item.Properties[FrameworkElement.HorizontalAlignmentProperty].ValueOnInstance; |
|
||||||
VerticalAlignment va = (VerticalAlignment)info.Item.Properties[FrameworkElement.VerticalAlignmentProperty].ValueOnInstance; |
|
||||||
|
|
||||||
if (ha == HorizontalAlignment.Stretch) |
|
||||||
info.Item.Properties[FrameworkElement.WidthProperty].SetValue(info.Bounds.Width); |
|
||||||
if (va == VerticalAlignment.Stretch) |
|
||||||
info.Item.Properties[FrameworkElement.HeightProperty].SetValue(info.Bounds.Height); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,52 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision: 2667$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Windows.Controls; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions.Initializers |
|
||||||
{ |
|
||||||
[ExtensionFor(typeof(ContentControl))] |
|
||||||
public class ContentControlInitializer : DefaultInitializer |
|
||||||
{ |
|
||||||
public override void InitializeDefaults(DesignItem item) |
|
||||||
{ |
|
||||||
DesignItemProperty contentProperty = item.Properties["Content"]; |
|
||||||
if (contentProperty.ValueOnInstance == null) { |
|
||||||
contentProperty.SetValue(item.ComponentType.Name); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
[ExtensionFor(typeof(HeaderedContentControl))] |
|
||||||
public class HeaderedContentControlInitializer : DefaultInitializer |
|
||||||
{ |
|
||||||
public override void InitializeDefaults(DesignItem item) |
|
||||||
{ |
|
||||||
DesignItemProperty headerProperty = item.Properties["Header"]; |
|
||||||
if (headerProperty.ValueOnInstance == null) { |
|
||||||
headerProperty.SetValue(item.ComponentType.Name); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
[ExtensionFor(typeof(Shape))] |
|
||||||
public class ShapeInitializer : DefaultInitializer |
|
||||||
{ |
|
||||||
public override void InitializeDefaults(DesignItem item) |
|
||||||
{ |
|
||||||
DesignItemProperty fillProperty = item.Properties["Fill"]; |
|
||||||
if (fillProperty.ValueOnInstance == null) { |
|
||||||
fillProperty.SetValue(Brushes.YellowGreen); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,161 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.ComponentModel; |
|
||||||
using System.Linq; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Controls; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Instance factory used to create Panel instances.
|
|
||||||
/// Sets the panels Brush to a transparent brush, and modifies the panel's type descriptor so that
|
|
||||||
/// the property value is reported as null when the transparent brush is used, and
|
|
||||||
/// setting the Brush to null actually restores the transparent brush.
|
|
||||||
/// </summary>
|
|
||||||
[ExtensionFor(typeof(Panel))] |
|
||||||
public sealed class PanelInstanceFactory : CustomInstanceFactory |
|
||||||
{ |
|
||||||
Brush _transparentBrush = new SolidColorBrush(Colors.Transparent); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates an instance of the specified type, passing the specified arguments to its constructor.
|
|
||||||
/// </summary>
|
|
||||||
public override object CreateInstance(Type type, params object[] arguments) |
|
||||||
{ |
|
||||||
object instance = base.CreateInstance(type, arguments); |
|
||||||
Panel panel = instance as Panel; |
|
||||||
if (panel != null) { |
|
||||||
if (panel.Background == null) { |
|
||||||
panel.Background = _transparentBrush; |
|
||||||
} |
|
||||||
TypeDescriptionProvider provider = new DummyValueInsteadOfNullTypeDescriptionProvider( |
|
||||||
TypeDescriptor.GetProvider(panel), "Background", _transparentBrush); |
|
||||||
TypeDescriptor.AddProvider(provider, panel); |
|
||||||
} |
|
||||||
return instance; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class DummyValueInsteadOfNullTypeDescriptionProvider : TypeDescriptionProvider |
|
||||||
{ |
|
||||||
// By using a TypeDescriptionProvider, we can intercept all access to the property that is
|
|
||||||
// using a PropertyDescriptor. WpfDesign.XamlDom uses a PropertyDescriptor for accessing
|
|
||||||
// properties (except for attached properties), so even DesignItemProperty/XamlProperty.ValueOnInstance
|
|
||||||
// will report null when the actual value is the dummy value.
|
|
||||||
|
|
||||||
readonly string _propertyName; |
|
||||||
readonly object _dummyValue; |
|
||||||
|
|
||||||
public DummyValueInsteadOfNullTypeDescriptionProvider(TypeDescriptionProvider existingProvider, |
|
||||||
string propertyName, object dummyValue) |
|
||||||
: base(existingProvider) |
|
||||||
{ |
|
||||||
this._propertyName = propertyName; |
|
||||||
this._dummyValue = dummyValue; |
|
||||||
} |
|
||||||
|
|
||||||
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) |
|
||||||
{ |
|
||||||
return new ShadowTypeDescriptor(this, base.GetTypeDescriptor(objectType, instance)); |
|
||||||
} |
|
||||||
|
|
||||||
sealed class ShadowTypeDescriptor : CustomTypeDescriptor |
|
||||||
{ |
|
||||||
readonly DummyValueInsteadOfNullTypeDescriptionProvider _parent; |
|
||||||
|
|
||||||
public ShadowTypeDescriptor(DummyValueInsteadOfNullTypeDescriptionProvider parent, |
|
||||||
ICustomTypeDescriptor existingDescriptor) |
|
||||||
: base(existingDescriptor) |
|
||||||
{ |
|
||||||
this._parent = parent; |
|
||||||
} |
|
||||||
|
|
||||||
public override PropertyDescriptorCollection GetProperties() |
|
||||||
{ |
|
||||||
return Filter(base.GetProperties()); |
|
||||||
} |
|
||||||
|
|
||||||
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) |
|
||||||
{ |
|
||||||
return Filter(base.GetProperties(attributes)); |
|
||||||
} |
|
||||||
|
|
||||||
PropertyDescriptorCollection Filter(PropertyDescriptorCollection properties) |
|
||||||
{ |
|
||||||
PropertyDescriptor property = properties[_parent._propertyName]; |
|
||||||
if (property != null) { |
|
||||||
if ((properties as System.Collections.IDictionary).IsReadOnly) { |
|
||||||
properties = new PropertyDescriptorCollection(properties.Cast<PropertyDescriptor>().ToArray()); |
|
||||||
} |
|
||||||
properties.Remove(property); |
|
||||||
properties.Add(new ShadowPropertyDescriptor(_parent, property)); |
|
||||||
} |
|
||||||
return properties; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class ShadowPropertyDescriptor : PropertyDescriptor |
|
||||||
{ |
|
||||||
readonly DummyValueInsteadOfNullTypeDescriptionProvider _parent; |
|
||||||
readonly PropertyDescriptor _baseDescriptor; |
|
||||||
|
|
||||||
public ShadowPropertyDescriptor(DummyValueInsteadOfNullTypeDescriptionProvider parent, |
|
||||||
PropertyDescriptor existingDescriptor) |
|
||||||
: base(existingDescriptor) |
|
||||||
{ |
|
||||||
this._parent = parent; |
|
||||||
this._baseDescriptor = existingDescriptor; |
|
||||||
} |
|
||||||
|
|
||||||
public override Type ComponentType { |
|
||||||
get { return _baseDescriptor.ComponentType; } |
|
||||||
} |
|
||||||
|
|
||||||
public override bool IsReadOnly { |
|
||||||
get { return _baseDescriptor.IsReadOnly; } |
|
||||||
} |
|
||||||
|
|
||||||
public override Type PropertyType { |
|
||||||
get { return _baseDescriptor.PropertyType; } |
|
||||||
} |
|
||||||
|
|
||||||
public override bool CanResetValue(object component) |
|
||||||
{ |
|
||||||
return _baseDescriptor.CanResetValue(component); |
|
||||||
} |
|
||||||
|
|
||||||
public override object GetValue(object component) |
|
||||||
{ |
|
||||||
object value = _baseDescriptor.GetValue(component); |
|
||||||
if (value == _parent._dummyValue) |
|
||||||
return null; |
|
||||||
else |
|
||||||
return value; |
|
||||||
} |
|
||||||
|
|
||||||
public override void ResetValue(object component) |
|
||||||
{ |
|
||||||
_baseDescriptor.SetValue(component, _parent._dummyValue); |
|
||||||
} |
|
||||||
|
|
||||||
public override void SetValue(object component, object value) |
|
||||||
{ |
|
||||||
_baseDescriptor.SetValue(component, value ?? _parent._dummyValue); |
|
||||||
} |
|
||||||
|
|
||||||
public override bool ShouldSerializeValue(object component) |
|
||||||
{ |
|
||||||
return _baseDescriptor.ShouldSerializeValue(component) |
|
||||||
&& _baseDescriptor.GetValue(component) != _parent._dummyValue; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,27 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Controls; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
[ExtensionFor(typeof(Panel))] |
|
||||||
public class PanelMove : PermanentAdornerProvider |
|
||||||
{ |
|
||||||
protected override void OnInitialized() |
|
||||||
{ |
|
||||||
base.OnInitialized(); |
|
||||||
|
|
||||||
var adornerPanel = new AdornerPanel(); |
|
||||||
var adorner = new PanelMoveAdorner(ExtendedItem); |
|
||||||
AdornerPanel.SetPlacement(adorner, AdornerPlacement.FillContent); |
|
||||||
adornerPanel.Children.Add(adorner); |
|
||||||
Adorners.Add(adornerPanel); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,170 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Controls; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Services; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Handles selection multiple controls inside a Panel.
|
|
||||||
/// </summary>
|
|
||||||
[ExtensionFor(typeof(Panel))] |
|
||||||
public class PanelSelectionHandler : BehaviorExtension, IHandlePointerToolMouseDown |
|
||||||
{ |
|
||||||
protected override void OnInitialized() |
|
||||||
{ |
|
||||||
base.OnInitialized(); |
|
||||||
this.ExtendedItem.AddBehavior(typeof(IHandlePointerToolMouseDown), this); |
|
||||||
} |
|
||||||
|
|
||||||
public void HandleSelectionMouseDown(IDesignPanel designPanel, MouseButtonEventArgs e, DesignPanelHitTestResult result) |
|
||||||
{ |
|
||||||
if (e.ChangedButton == MouseButton.Left && MouseGestureBase.IsOnlyButtonPressed(e, MouseButton.Left)) { |
|
||||||
e.Handled = true; |
|
||||||
new RangeSelectionGesture(result.ModelHit).Start(designPanel, e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
sealed class RangeSelectionGesture : ClickOrDragMouseGesture |
|
||||||
{ |
|
||||||
DesignItem container; |
|
||||||
AdornerPanel adornerPanel; |
|
||||||
SelectionFrame selectionFrame; |
|
||||||
|
|
||||||
GrayOutDesignerExceptActiveArea grayOut; |
|
||||||
|
|
||||||
public RangeSelectionGesture(DesignItem container) |
|
||||||
{ |
|
||||||
this.container = container; |
|
||||||
this.positionRelativeTo = container.View; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnDragStarted(MouseEventArgs e) |
|
||||||
{ |
|
||||||
adornerPanel = new AdornerPanel(); |
|
||||||
adornerPanel.SetAdornedElement(container.View, container); |
|
||||||
|
|
||||||
selectionFrame = new SelectionFrame(); |
|
||||||
adornerPanel.Children.Add(selectionFrame); |
|
||||||
|
|
||||||
designPanel.Adorners.Add(adornerPanel); |
|
||||||
|
|
||||||
GrayOutDesignerExceptActiveArea.Start(ref grayOut, services, container.View); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseMove(object sender, MouseEventArgs e) |
|
||||||
{ |
|
||||||
base.OnMouseMove(sender, e); |
|
||||||
if (hasDragStarted) { |
|
||||||
SetPlacement(e.GetPosition(positionRelativeTo)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseUp(object sender, MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
if (hasDragStarted == false) { |
|
||||||
services.Selection.SetSelectedComponents(new DesignItem [] { container }, SelectionTypes.Auto); |
|
||||||
} else { |
|
||||||
Point endPoint = e.GetPosition(positionRelativeTo); |
|
||||||
Rect frameRect = new Rect( |
|
||||||
Math.Min(startPoint.X, endPoint.X), |
|
||||||
Math.Min(startPoint.Y, endPoint.Y), |
|
||||||
Math.Abs(startPoint.X - endPoint.X), |
|
||||||
Math.Abs(startPoint.Y - endPoint.Y) |
|
||||||
); |
|
||||||
|
|
||||||
ICollection<DesignItem> items = GetChildDesignItemsInContainer(container, new RectangleGeometry(frameRect)); |
|
||||||
if (items.Count == 0) { |
|
||||||
items.Add(container); |
|
||||||
} |
|
||||||
services.Selection.SetSelectedComponents(items, SelectionTypes.Auto); |
|
||||||
} |
|
||||||
Stop(); |
|
||||||
} |
|
||||||
|
|
||||||
static ICollection<DesignItem> GetChildDesignItemsInContainer( |
|
||||||
DesignItem container, Geometry geometry) |
|
||||||
{ |
|
||||||
HashSet<DesignItem> resultItems = new HashSet<DesignItem>(); |
|
||||||
ViewService viewService = container.Services.View; |
|
||||||
|
|
||||||
HitTestFilterCallback filterCallback = delegate(DependencyObject potentialHitTestTarget) { |
|
||||||
FrameworkElement element = potentialHitTestTarget as FrameworkElement; |
|
||||||
if (element != null) { |
|
||||||
// ensure we are able to select elements with width/height=0
|
|
||||||
if (element.ActualWidth == 0 || element.ActualHeight == 0) { |
|
||||||
DependencyObject tmp = element; |
|
||||||
DesignItem model = null; |
|
||||||
while (tmp != null) { |
|
||||||
model = viewService.GetModel(tmp); |
|
||||||
if (model != null) break; |
|
||||||
tmp = VisualTreeHelper.GetParent(tmp); |
|
||||||
} |
|
||||||
if (model != container) { |
|
||||||
resultItems.Add(model); |
|
||||||
return HitTestFilterBehavior.ContinueSkipChildren; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return HitTestFilterBehavior.Continue; |
|
||||||
}; |
|
||||||
|
|
||||||
HitTestResultCallback resultCallback = delegate(HitTestResult result) { |
|
||||||
if (((GeometryHitTestResult) result).IntersectionDetail == IntersectionDetail.FullyInside) { |
|
||||||
// find the model for the visual contained in the selection area
|
|
||||||
DependencyObject tmp = result.VisualHit; |
|
||||||
DesignItem model = null; |
|
||||||
while (tmp != null) { |
|
||||||
model = viewService.GetModel(tmp); |
|
||||||
if (model != null) break; |
|
||||||
tmp = VisualTreeHelper.GetParent(tmp); |
|
||||||
} |
|
||||||
if (model != container) { |
|
||||||
resultItems.Add(model); |
|
||||||
} |
|
||||||
} |
|
||||||
return HitTestResultBehavior.Continue; |
|
||||||
}; |
|
||||||
|
|
||||||
VisualTreeHelper.HitTest(container.View, filterCallback, resultCallback, new GeometryHitTestParameters(geometry)); |
|
||||||
return resultItems; |
|
||||||
} |
|
||||||
|
|
||||||
void SetPlacement(Point endPoint) |
|
||||||
{ |
|
||||||
RelativePlacement p = new RelativePlacement(); |
|
||||||
p.XOffset = Math.Min(startPoint.X, endPoint.X); |
|
||||||
p.YOffset = Math.Min(startPoint.Y, endPoint.Y); |
|
||||||
p.WidthOffset = Math.Max(startPoint.X, endPoint.X) - p.XOffset; |
|
||||||
p.HeightOffset = Math.Max(startPoint.Y, endPoint.Y) - p.YOffset; |
|
||||||
AdornerPanel.SetPlacement(selectionFrame, p); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnStopped() |
|
||||||
{ |
|
||||||
if (adornerPanel != null) { |
|
||||||
designPanel.Adorners.Remove(adornerPanel); |
|
||||||
adornerPanel = null; |
|
||||||
} |
|
||||||
GrayOutDesignerExceptActiveArea.Stop(ref grayOut); |
|
||||||
selectionFrame = null; |
|
||||||
base.OnStopped(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,150 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
using System.Windows.Input; |
|
||||||
|
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Controls; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
using System.Collections.Generic; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// The resize thumb around a component.
|
|
||||||
/// </summary>
|
|
||||||
[ExtensionFor(typeof(FrameworkElement))] |
|
||||||
public sealed class ResizeThumbExtension : PrimarySelectionAdornerProvider |
|
||||||
{ |
|
||||||
readonly AdornerPanel adornerPanel; |
|
||||||
readonly ResizeThumb[] resizeThumbs; |
|
||||||
/// <summary>An array containing this.ExtendedItem as only element</summary>
|
|
||||||
readonly DesignItem[] extendedItemArray = new DesignItem[1]; |
|
||||||
IPlacementBehavior resizeBehavior; |
|
||||||
PlacementOperation operation; |
|
||||||
ChangeGroup changeGroup; |
|
||||||
|
|
||||||
public ResizeThumbExtension() |
|
||||||
{ |
|
||||||
adornerPanel = new AdornerPanel(); |
|
||||||
adornerPanel.Order = AdornerOrder.Foreground; |
|
||||||
this.Adorners.Add(adornerPanel); |
|
||||||
|
|
||||||
resizeThumbs = new ResizeThumb[] { |
|
||||||
CreateThumb(PlacementAlignment.TopLeft, Cursors.SizeNWSE), |
|
||||||
CreateThumb(PlacementAlignment.Top, Cursors.SizeNS), |
|
||||||
CreateThumb(PlacementAlignment.TopRight, Cursors.SizeNESW), |
|
||||||
CreateThumb(PlacementAlignment.Left, Cursors.SizeWE), |
|
||||||
CreateThumb(PlacementAlignment.Right, Cursors.SizeWE), |
|
||||||
CreateThumb(PlacementAlignment.BottomLeft, Cursors.SizeNESW), |
|
||||||
CreateThumb(PlacementAlignment.Bottom, Cursors.SizeNS), |
|
||||||
CreateThumb(PlacementAlignment.BottomRight, Cursors.SizeNWSE) |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
ResizeThumb CreateThumb(PlacementAlignment alignment, Cursor cursor) |
|
||||||
{ |
|
||||||
ResizeThumb resizeThumb = new ResizeThumbImpl( cursor == Cursors.SizeNS, cursor == Cursors.SizeWE ); |
|
||||||
resizeThumb.Cursor = cursor; |
|
||||||
resizeThumb.Alignment = alignment; |
|
||||||
AdornerPanel.SetPlacement(resizeThumb, new RelativePlacement(alignment.Horizontal, alignment.Vertical)); |
|
||||||
adornerPanel.Children.Add(resizeThumb); |
|
||||||
|
|
||||||
DragListener drag = new DragListener(resizeThumb); |
|
||||||
drag.Started += new DragHandler(drag_Started); |
|
||||||
drag.Changed += new DragHandler(drag_Changed); |
|
||||||
drag.Completed += new DragHandler(drag_Completed); |
|
||||||
return resizeThumb; |
|
||||||
} |
|
||||||
|
|
||||||
Size oldSize; |
|
||||||
|
|
||||||
void drag_Started(DragListener drag) |
|
||||||
{ |
|
||||||
oldSize = new Size(ModelTools.GetWidth(ExtendedItem.View), ModelTools.GetHeight(ExtendedItem.View)); |
|
||||||
if (resizeBehavior != null) |
|
||||||
operation = PlacementOperation.Start(extendedItemArray, PlacementType.Resize); |
|
||||||
else { |
|
||||||
changeGroup = this.ExtendedItem.Context.OpenGroup("Resize", extendedItemArray); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void drag_Changed(DragListener drag) |
|
||||||
{ |
|
||||||
double dx = 0; |
|
||||||
double dy = 0; |
|
||||||
var alignment = (drag.Target as ResizeThumb).Alignment; |
|
||||||
|
|
||||||
if (alignment.Horizontal == HorizontalAlignment.Left) dx = -drag.Delta.X; |
|
||||||
if (alignment.Horizontal == HorizontalAlignment.Right) dx = drag.Delta.X; |
|
||||||
if (alignment.Vertical == VerticalAlignment.Top) dy = -drag.Delta.Y; |
|
||||||
if (alignment.Vertical == VerticalAlignment.Bottom) dy = drag.Delta.Y; |
|
||||||
|
|
||||||
var newWidth = Math.Max(0, oldSize.Width + dx); |
|
||||||
var newHeight = Math.Max(0, oldSize.Height + dy); |
|
||||||
|
|
||||||
ModelTools.Resize(ExtendedItem, newWidth, newHeight); |
|
||||||
|
|
||||||
if (operation != null) { |
|
||||||
var info = operation.PlacedItems[0]; |
|
||||||
var result = info.OriginalBounds; |
|
||||||
|
|
||||||
if (alignment.Horizontal == HorizontalAlignment.Left) |
|
||||||
result.X = Math.Min(result.Right, result.X - dx); |
|
||||||
if (alignment.Vertical == VerticalAlignment.Top) |
|
||||||
result.Y = Math.Min(result.Bottom, result.Y - dy); |
|
||||||
result.Width = newWidth; |
|
||||||
result.Height = newHeight; |
|
||||||
|
|
||||||
info.Bounds = result; |
|
||||||
info.ResizeThumbAlignment = alignment; |
|
||||||
operation.CurrentContainerBehavior.BeforeSetPosition(operation); |
|
||||||
operation.CurrentContainerBehavior.SetPosition(info); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void drag_Completed(DragListener drag) |
|
||||||
{ |
|
||||||
if (operation != null) { |
|
||||||
if (drag.IsCanceled) operation.Abort(); |
|
||||||
else operation.Commit(); |
|
||||||
operation = null; |
|
||||||
} else { |
|
||||||
if (drag.IsCanceled) changeGroup.Abort(); |
|
||||||
else changeGroup.Commit(); |
|
||||||
changeGroup = null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnInitialized() |
|
||||||
{ |
|
||||||
base.OnInitialized(); |
|
||||||
extendedItemArray[0] = this.ExtendedItem; |
|
||||||
this.Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged; |
|
||||||
resizeBehavior = PlacementOperation.GetPlacementBehavior(extendedItemArray); |
|
||||||
OnPrimarySelectionChanged(null, null); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnRemove() |
|
||||||
{ |
|
||||||
this.Services.Selection.PrimarySelectionChanged -= OnPrimarySelectionChanged; |
|
||||||
base.OnRemove(); |
|
||||||
} |
|
||||||
|
|
||||||
void OnPrimarySelectionChanged(object sender, EventArgs e) |
|
||||||
{ |
|
||||||
bool isPrimarySelection = this.Services.Selection.PrimarySelection == this.ExtendedItem; |
|
||||||
foreach (ResizeThumb g in adornerPanel.Children) { |
|
||||||
g.IsPrimarySelection = isPrimarySelection; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,50 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Shapes; |
|
||||||
|
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Draws a dotted line around selected UIElements.
|
|
||||||
/// </summary>
|
|
||||||
[ExtensionFor(typeof(UIElement))] |
|
||||||
public sealed class SelectedElementRectangleExtension : SelectionAdornerProvider |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Creates a new SelectedElementRectangleExtension instance.
|
|
||||||
/// </summary>
|
|
||||||
public SelectedElementRectangleExtension() |
|
||||||
{ |
|
||||||
Rectangle selectionRect = new Rectangle(); |
|
||||||
selectionRect.SnapsToDevicePixels = true; |
|
||||||
selectionRect.Stroke = Brushes.White; |
|
||||||
selectionRect.IsHitTestVisible = false; |
|
||||||
|
|
||||||
Rectangle dottedRect = new Rectangle(); |
|
||||||
dottedRect.SnapsToDevicePixels = true; |
|
||||||
dottedRect.Stroke = Brushes.Black; |
|
||||||
dottedRect.StrokeDashCap = PenLineCap.Square; |
|
||||||
dottedRect.StrokeDashArray = new DoubleCollection(new double[] { 0, 2 }); |
|
||||||
dottedRect.IsHitTestVisible = false; |
|
||||||
|
|
||||||
RelativePlacement placement = new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Stretch); |
|
||||||
placement.XOffset = -1; |
|
||||||
placement.YOffset = -1; |
|
||||||
placement.WidthOffset = 2; |
|
||||||
placement.HeightOffset = 2; |
|
||||||
|
|
||||||
this.AddAdorners(placement, selectionRect, dottedRect); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,312 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
using System.ComponentModel; |
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Windows.Automation.Peers; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Windows.Input; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
public class SnaplinePlacementBehavior : DefaultPlacementBehavior |
|
||||||
{ |
|
||||||
AdornerPanel adornerPanel; |
|
||||||
Canvas surface; |
|
||||||
List<Snapline> horizontalMap; |
|
||||||
List<Snapline> verticalMap; |
|
||||||
double? baseline; |
|
||||||
|
|
||||||
public static double Accuracy = 5; |
|
||||||
public static double Margin = 8; |
|
||||||
|
|
||||||
public override void BeginPlacement(PlacementOperation operation) |
|
||||||
{ |
|
||||||
base.BeginPlacement(operation); |
|
||||||
CreateSurface(operation); |
|
||||||
} |
|
||||||
|
|
||||||
public override void EndPlacement(PlacementOperation operation) |
|
||||||
{ |
|
||||||
base.EndPlacement(operation); |
|
||||||
DeleteSurface(); |
|
||||||
} |
|
||||||
|
|
||||||
public override void EnterContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
base.EnterContainer(operation); |
|
||||||
CreateSurface(operation); |
|
||||||
} |
|
||||||
|
|
||||||
public override void LeaveContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
base.LeaveContainer(operation); |
|
||||||
DeleteSurface(); |
|
||||||
} |
|
||||||
|
|
||||||
public override void BeforeSetPosition(PlacementOperation operation) |
|
||||||
{ |
|
||||||
base.BeforeSetPosition(operation); |
|
||||||
if (surface == null) return; |
|
||||||
|
|
||||||
surface.Children.Clear(); |
|
||||||
if (Keyboard.IsKeyDown(Key.LeftCtrl)) return; |
|
||||||
|
|
||||||
Rect bounds = Rect.Empty; |
|
||||||
foreach (var item in operation.PlacedItems) { |
|
||||||
bounds.Union(item.Bounds); |
|
||||||
} |
|
||||||
|
|
||||||
var horizontalInput = new List<Snapline>(); |
|
||||||
var verticalInput = new List<Snapline>(); |
|
||||||
var info = operation.PlacedItems[0]; |
|
||||||
|
|
||||||
if (operation.Type == PlacementType.Resize) { |
|
||||||
AddLines(bounds, 0, false, horizontalInput, verticalInput, info.ResizeThumbAlignment); |
|
||||||
} else { |
|
||||||
AddLines(bounds, 0, false, horizontalInput, verticalInput, null); |
|
||||||
if (baseline.HasValue) { |
|
||||||
var textOffset = bounds.Top + baseline.Value; |
|
||||||
horizontalInput.Add(new Snapline() { Group = 1, Offset = textOffset, Start = bounds.Left, End = bounds.Right }); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// debug
|
|
||||||
//foreach (var t in horizontalMap.Concat(horizontalInput)) {
|
|
||||||
// surface.Children.Add(new Line() { X1 = t.Start, X2 = t.End, Y1 = t.Offset, Y2 = t.Offset, Stroke = Brushes.Black });
|
|
||||||
//}
|
|
||||||
//foreach (var t in verticalMap.Concat(verticalInput)) {
|
|
||||||
// surface.Children.Add(new Line() { X1 = t.Offset, X2 = t.Offset, Y1 = t.Start , Y2 = t.End, Stroke = Brushes.Black });
|
|
||||||
//}
|
|
||||||
//return;
|
|
||||||
|
|
||||||
List<Snapline> drawLines; |
|
||||||
double delta; |
|
||||||
|
|
||||||
if (Snap(horizontalInput, horizontalMap, Accuracy, out drawLines, out delta)) { |
|
||||||
|
|
||||||
if (operation.Type == PlacementType.Resize) { |
|
||||||
if (info.ResizeThumbAlignment.Vertical == VerticalAlignment.Top) { |
|
||||||
bounds.Y += delta; |
|
||||||
bounds.Height = Math.Max(0, bounds.Height - delta); |
|
||||||
} else { |
|
||||||
bounds.Height = Math.Max(0, bounds.Height + delta); |
|
||||||
} |
|
||||||
info.Bounds = bounds; |
|
||||||
} else { |
|
||||||
foreach (var item in operation.PlacedItems) { |
|
||||||
var r = item.Bounds; |
|
||||||
r.Y += delta; |
|
||||||
item.Bounds = r; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
foreach (var d in drawLines) { |
|
||||||
DrawLine(d.Start, d.Offset, d.End, d.Offset); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (Snap(verticalInput, verticalMap, Accuracy, out drawLines, out delta)) { |
|
||||||
|
|
||||||
if (operation.Type == PlacementType.Resize) { |
|
||||||
if (info.ResizeThumbAlignment.Horizontal == HorizontalAlignment.Left) { |
|
||||||
bounds.X += delta; |
|
||||||
bounds.Width = Math.Max(0, bounds.Width - delta); |
|
||||||
} else { |
|
||||||
bounds.Width = Math.Max(0, bounds.Width + delta); |
|
||||||
} |
|
||||||
info.Bounds = bounds; |
|
||||||
} else { |
|
||||||
foreach (var item in operation.PlacedItems) { |
|
||||||
var r = item.Bounds; |
|
||||||
r.X += delta; |
|
||||||
item.Bounds = r; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
foreach (var d in drawLines) { |
|
||||||
DrawLine(d.Offset, d.Start, d.Offset, d.End); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void CreateSurface(PlacementOperation operation) |
|
||||||
{ |
|
||||||
if (ExtendedItem.Services.GetService<IDesignPanel>() != null) { |
|
||||||
|
|
||||||
surface = new Canvas(); |
|
||||||
adornerPanel = new AdornerPanel(); |
|
||||||
adornerPanel.SetAdornedElement(ExtendedItem.View, ExtendedItem); |
|
||||||
AdornerPanel.SetPlacement(surface, AdornerPlacement.FillContent); |
|
||||||
adornerPanel.Children.Add(surface); |
|
||||||
ExtendedItem.Services.DesignPanel.Adorners.Add(adornerPanel); |
|
||||||
|
|
||||||
BuildMaps(operation); |
|
||||||
|
|
||||||
if (operation.Type != PlacementType.Resize && operation.PlacedItems.Count == 1) { |
|
||||||
baseline = GetBaseline(operation.PlacedItems[0].Item.View); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void BuildMaps(PlacementOperation operation) |
|
||||||
{ |
|
||||||
horizontalMap = new List<Snapline>(); |
|
||||||
verticalMap = new List<Snapline>(); |
|
||||||
|
|
||||||
var containerRect = new Rect(0, 0, ModelTools.GetWidth(ExtendedItem.View), ModelTools.GetHeight(ExtendedItem.View)); |
|
||||||
AddLines(containerRect, -Margin, false); |
|
||||||
|
|
||||||
foreach (var item in ExtendedItem.ContentProperty.CollectionElements |
|
||||||
.Except(operation.PlacedItems.Select(f => f.Item))) |
|
||||||
{ |
|
||||||
var bounds = GetPosition(operation, item); |
|
||||||
|
|
||||||
AddLines(bounds, 0, false); |
|
||||||
AddLines(bounds, Margin, true); |
|
||||||
AddBaseline(item, bounds, horizontalMap); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void AddLines(Rect r, double inflate, bool requireOverlap) |
|
||||||
{ |
|
||||||
AddLines(r, inflate, requireOverlap, horizontalMap, verticalMap, null); |
|
||||||
} |
|
||||||
|
|
||||||
void AddLines(Rect r, double inflate, bool requireOverlap, List<Snapline> h, List<Snapline> v, PlacementAlignment? filter) |
|
||||||
{ |
|
||||||
Rect r2 = r; |
|
||||||
r2.Inflate(inflate, inflate); |
|
||||||
|
|
||||||
if (filter == null || filter.Value.Vertical == VerticalAlignment.Top) |
|
||||||
h.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Top - 1, Start = r.Left, End = r.Right }); |
|
||||||
if (filter == null || filter.Value.Vertical == VerticalAlignment.Bottom) |
|
||||||
h.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Bottom, Start = r.Left, End = r.Right }); |
|
||||||
if (filter == null || filter.Value.Horizontal == HorizontalAlignment.Left) |
|
||||||
v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Left - 1, Start = r.Top, End = r.Bottom }); |
|
||||||
if (filter == null || filter.Value.Horizontal == HorizontalAlignment.Right) |
|
||||||
v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Right, Start = r.Top, End = r.Bottom }); |
|
||||||
} |
|
||||||
|
|
||||||
void AddBaseline(DesignItem item, Rect bounds, List<Snapline> list) |
|
||||||
{ |
|
||||||
var baseline = GetBaseline(item.View); |
|
||||||
if (baseline.HasValue) { |
|
||||||
var textOffset = item.View.TranslatePoint(new Point(0, baseline.Value), ExtendedItem.View).Y; |
|
||||||
list.Add(new Snapline() { Group = 1, Offset = textOffset, Start = bounds.Left, End = bounds.Right }); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void DeleteSurface() |
|
||||||
{ |
|
||||||
if (surface != null) { |
|
||||||
ExtendedItem.Services.DesignPanel.Adorners.Remove(adornerPanel); |
|
||||||
adornerPanel = null; |
|
||||||
surface = null; |
|
||||||
horizontalMap = null; |
|
||||||
verticalMap = null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void DrawLine(double x1, double y1, double x2, double y2) |
|
||||||
{ |
|
||||||
var line1 = new Line() { |
|
||||||
X1 = x1, |
|
||||||
Y1 = y1, |
|
||||||
X2 = x2, |
|
||||||
Y2 = y2, |
|
||||||
StrokeThickness = 1, |
|
||||||
Stroke = Brushes.White |
|
||||||
}; |
|
||||||
surface.Children.Add(line1); |
|
||||||
|
|
||||||
var line2 = new Line() { |
|
||||||
X1 = x1, |
|
||||||
Y1 = y1, |
|
||||||
X2 = x2, |
|
||||||
Y2 = y2, |
|
||||||
StrokeThickness = 1, |
|
||||||
Stroke = Brushes.Orange, |
|
||||||
StrokeDashArray = new DoubleCollection(new double[] { 5, 2 }), |
|
||||||
StrokeDashOffset = x1 + y1 // fix dashes
|
|
||||||
}; |
|
||||||
surface.Children.Add(line2); |
|
||||||
} |
|
||||||
|
|
||||||
//TODO: GlyphRun must be used
|
|
||||||
static double? GetBaseline(UIElement element) { |
|
||||||
var textBox = element.FindChild<TextBox>(); |
|
||||||
if (textBox != null) { |
|
||||||
var r = textBox.GetRectFromCharacterIndex(0).Bottom; |
|
||||||
return textBox.TranslatePoint(new Point(0, r), element).Y; |
|
||||||
} |
|
||||||
var textBlock = element.FindChild<TextBlock>(); |
|
||||||
if (textBlock != null) |
|
||||||
return textBlock.TranslatePoint(new Point(0, textBlock.ActualHeight), element).Y; |
|
||||||
|
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
static bool Snap(List<Snapline> input, List<Snapline> map, double accuracy, |
|
||||||
out List<Snapline> drawLines, out double delta) |
|
||||||
{ |
|
||||||
delta = double.MaxValue; |
|
||||||
drawLines = null; |
|
||||||
|
|
||||||
foreach (var inputLine in input) { |
|
||||||
foreach (var mapLine in map) { |
|
||||||
if (Math.Abs(mapLine.Offset - inputLine.Offset) <= accuracy) { |
|
||||||
if (!inputLine.RequireOverlap && !mapLine.RequireOverlap || |
|
||||||
Math.Max(inputLine.Start, mapLine.Start) < Math.Min(inputLine.End, mapLine.End)) |
|
||||||
{ |
|
||||||
if (mapLine.Group == inputLine.Group) |
|
||||||
delta = mapLine.Offset - inputLine.Offset; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (delta == double.MaxValue) return false; |
|
||||||
var offsetDict = new Dictionary<double, Snapline>(); |
|
||||||
|
|
||||||
foreach (var inputLine in input) { |
|
||||||
inputLine.Offset += delta; |
|
||||||
foreach (var mapLine in map) { |
|
||||||
if (inputLine.Offset == mapLine.Offset) { |
|
||||||
var offset = mapLine.Offset; |
|
||||||
Snapline drawLine; |
|
||||||
if (!offsetDict.TryGetValue(offset, out drawLine)) { |
|
||||||
drawLine = new Snapline(); |
|
||||||
drawLine.Start = double.MaxValue; |
|
||||||
drawLine.End = double.MinValue; |
|
||||||
offsetDict[offset] = drawLine; |
|
||||||
} |
|
||||||
drawLine.Offset = offset; |
|
||||||
drawLine.Start = Math.Min(drawLine.Start, Math.Min(inputLine.Start, mapLine.Start)); |
|
||||||
drawLine.End = Math.Max(drawLine.End, Math.Max(inputLine.End, mapLine.End)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
drawLines = offsetDict.Values.ToList(); |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
[DebuggerDisplay("Snapline: {Offset}")] |
|
||||||
class Snapline |
|
||||||
{ |
|
||||||
public double Offset; |
|
||||||
public double Start; |
|
||||||
public double End; |
|
||||||
public bool RequireOverlap; |
|
||||||
public int Group; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,32 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Windows.Controls; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Makes TabItems clickable.
|
|
||||||
/// </summary>
|
|
||||||
[ExtensionFor(typeof(TabItem))] |
|
||||||
[ExtensionServer(typeof(PrimarySelectionExtensionServer))] |
|
||||||
public sealed class TabItemClickableExtension : DefaultExtension |
|
||||||
{ |
|
||||||
/// <summary/>
|
|
||||||
protected override void OnInitialized() |
|
||||||
{ |
|
||||||
// When tab item becomes primary selection, make it the active tab page in its parent tab control.
|
|
||||||
TabItem tabItem = (TabItem)this.ExtendedItem.Component; |
|
||||||
TabControl tabControl = tabItem.Parent as TabControl; |
|
||||||
if (tabControl != null) { |
|
||||||
tabControl.SelectedItem = tabItem; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,44 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using ICSharpCode.WpfDesign.Adorners; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
using ICSharpCode.WpfDesign.Designer.Controls; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
/* |
|
||||||
/// <summary>
|
|
||||||
/// The drag handle displayed for panels.
|
|
||||||
/// </summary>
|
|
||||||
[ExtensionServer(typeof(PrimarySelectionExtensionServer))] |
|
||||||
[ExtensionFor(typeof(Panel), OverrideExtension = typeof(TopLeftResizeThumb))] |
|
||||||
public class TopLeftContainerDragHandle : AdornerProvider |
|
||||||
{ |
|
||||||
/// <summary/>
|
|
||||||
public TopLeftContainerDragHandle() |
|
||||||
{ |
|
||||||
ContainerDragHandle rect = new ContainerDragHandle(); |
|
||||||
|
|
||||||
rect.PreviewMouseDown += delegate { |
|
||||||
Services.Selection.SetSelectedComponents(new DesignItem[] { this.ExtendedItem }, SelectionTypes.Auto); |
|
||||||
}; |
|
||||||
|
|
||||||
RelativePlacement p = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Top); |
|
||||||
p.XOffset = -1; |
|
||||||
p.YOffset = -1; |
|
||||||
|
|
||||||
AddAdorner(p, AdornerOrder.Background, rect); |
|
||||||
} |
|
||||||
} |
|
||||||
*/ |
|
||||||
} |
|
||||||
@ -1,86 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Windows; |
|
||||||
using ICSharpCode.WpfDesign.Extensions; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Supports resizing a Window.
|
|
||||||
/// </summary>
|
|
||||||
[ExtensionFor(typeof(Window))] |
|
||||||
public class WindowResizeBehavior : BehaviorExtension, IRootPlacementBehavior |
|
||||||
{ |
|
||||||
protected override void OnInitialized() |
|
||||||
{ |
|
||||||
base.OnInitialized(); |
|
||||||
this.ExtendedItem.AddBehavior(typeof(IRootPlacementBehavior), this); |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanPlace(ICollection<DesignItem> children, PlacementType type, PlacementAlignment position) |
|
||||||
{ |
|
||||||
return type == PlacementType.Resize && |
|
||||||
(position == PlacementAlignment.Right |
|
||||||
|| position == PlacementAlignment.BottomRight |
|
||||||
|| position == PlacementAlignment.Bottom); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public void BeginPlacement(PlacementOperation operation) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public void EndPlacement(PlacementOperation operation) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public Rect GetPosition(PlacementOperation operation, DesignItem childItem) |
|
||||||
{ |
|
||||||
UIElement child = childItem.View; |
|
||||||
return new Rect(0, 0, ModelTools.GetWidth(child), ModelTools.GetHeight(child)); |
|
||||||
} |
|
||||||
|
|
||||||
public void BeforeSetPosition(PlacementOperation operation) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public void SetPosition(PlacementInformation info) |
|
||||||
{ |
|
||||||
UIElement element = info.Item.View; |
|
||||||
Rect newPosition = info.Bounds; |
|
||||||
if (newPosition.Right != ModelTools.GetWidth(element)) { |
|
||||||
info.Item.Properties[FrameworkElement.WidthProperty].SetValue(newPosition.Right); |
|
||||||
} |
|
||||||
if (newPosition.Bottom != ModelTools.GetHeight(element)) { |
|
||||||
info.Item.Properties[FrameworkElement.HeightProperty].SetValue(newPosition.Bottom); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanLeaveContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
public void LeaveContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
throw new NotSupportedException(); |
|
||||||
} |
|
||||||
|
|
||||||
public bool CanEnterContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
public void EnterContainer(PlacementOperation operation) |
|
||||||
{ |
|
||||||
throw new NotSupportedException(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
Before Width: | Height: | Size: 624 B |
|
Before Width: | Height: | Size: 326 B |
|
Before Width: | Height: | Size: 326 B |
|
Before Width: | Height: | Size: 389 B |
|
Before Width: | Height: | Size: 635 B |
|
Before Width: | Height: | Size: 647 B |
@ -1,139 +0,0 @@ |
|||||||
// <file>
|
|
||||||
// <copyright see="prj:///doc/copyright.txt"/>
|
|
||||||
// <license see="prj:///doc/license.txt"/>
|
|
||||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
|
||||||
// <version>$Revision$</version>
|
|
||||||
// </file>
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Windows; |
|
||||||
using System.Linq; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Static helper methods for working with the designer DOM.
|
|
||||||
/// </summary>
|
|
||||||
public static class ModelTools |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Compares the positions of a and b in the model file.
|
|
||||||
/// </summary>
|
|
||||||
public static int ComparePositionInModelFile(DesignItem a, DesignItem b) |
|
||||||
{ |
|
||||||
// first remember all parent properties of a
|
|
||||||
HashSet<DesignItemProperty> aProps = new HashSet<DesignItemProperty>(); |
|
||||||
DesignItem tmp = a; |
|
||||||
while (tmp != null) { |
|
||||||
aProps.Add(tmp.ParentProperty); |
|
||||||
tmp = tmp.Parent; |
|
||||||
} |
|
||||||
|
|
||||||
// now walk up b's parent tree until a matching property is found
|
|
||||||
tmp = b; |
|
||||||
while (tmp != null) { |
|
||||||
DesignItemProperty prop = tmp.ParentProperty; |
|
||||||
if (aProps.Contains(prop)) { |
|
||||||
if (prop.IsCollection) { |
|
||||||
return prop.CollectionElements.IndexOf(a).CompareTo(prop.CollectionElements.IndexOf(b)); |
|
||||||
} else { |
|
||||||
return 0; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the specified design item is in the document it belongs to.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True for live objects, false for deleted objects.</returns>
|
|
||||||
public static bool IsInDocument(DesignItem item) |
|
||||||
{ |
|
||||||
DesignItem rootItem = item.Context.RootItem; |
|
||||||
while (item != null) { |
|
||||||
if (item == rootItem) return true; |
|
||||||
item = item.Parent; |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the specified components can be deleted.
|
|
||||||
/// </summary>
|
|
||||||
public static bool CanDeleteComponents(ICollection<DesignItem> items) |
|
||||||
{ |
|
||||||
IPlacementBehavior b = PlacementOperation.GetPlacementBehavior(items); |
|
||||||
return b != null |
|
||||||
&& b.CanPlace(items, PlacementType.Delete, PlacementAlignment.Center); |
|
||||||
} |
|
||||||
|
|
||||||
public static bool CanSelectComponent(DesignItem item) |
|
||||||
{ |
|
||||||
return item.View != null; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes the specified components from their parent containers.
|
|
||||||
/// If the deleted components are currently selected, they are deselected before they are deleted.
|
|
||||||
/// </summary>
|
|
||||||
public static void DeleteComponents(ICollection<DesignItem> items) |
|
||||||
{ |
|
||||||
DesignItem parent = items.First().Parent; |
|
||||||
PlacementOperation operation = PlacementOperation.Start(items, PlacementType.Delete); |
|
||||||
try { |
|
||||||
ISelectionService selectionService = items.First().Services.Selection; |
|
||||||
selectionService.SetSelectedComponents(items, SelectionTypes.Remove); |
|
||||||
// if the selection is empty after deleting some components, select the parent of the deleted component
|
|
||||||
if (selectionService.SelectionCount == 0 && !items.Contains(parent)) { |
|
||||||
selectionService.SetSelectedComponents(new DesignItem[] { parent }); |
|
||||||
} |
|
||||||
operation.DeleteItemsAndCommit(); |
|
||||||
} catch { |
|
||||||
operation.Abort(); |
|
||||||
throw; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
internal static Size GetDefaultSize(DesignItem createdItem) |
|
||||||
{ |
|
||||||
var s = Metadata.GetDefaultSize(createdItem.ComponentType); |
|
||||||
if (double.IsNaN(s.Width)) { |
|
||||||
s.Width = GetWidth(createdItem.View); |
|
||||||
} |
|
||||||
if (double.IsNaN(s.Height)) { |
|
||||||
s.Height = GetHeight(createdItem.View); |
|
||||||
} |
|
||||||
return s; |
|
||||||
} |
|
||||||
|
|
||||||
internal static double GetWidth(UIElement element) |
|
||||||
{ |
|
||||||
double v = (double)element.GetValue(FrameworkElement.WidthProperty); |
|
||||||
if (double.IsNaN(v)) |
|
||||||
return element.RenderSize.Width; |
|
||||||
else |
|
||||||
return v; |
|
||||||
} |
|
||||||
|
|
||||||
internal static double GetHeight(UIElement element) |
|
||||||
{ |
|
||||||
double v = (double)element.GetValue(FrameworkElement.HeightProperty); |
|
||||||
if (double.IsNaN(v)) |
|
||||||
return element.RenderSize.Height; |
|
||||||
else |
|
||||||
return v; |
|
||||||
} |
|
||||||
|
|
||||||
public static void Resize(DesignItem item, double newWidth, double newHeight) |
|
||||||
{ |
|
||||||
if (newWidth != GetWidth(item.View)) { |
|
||||||
item.Properties.GetProperty(FrameworkElement.WidthProperty).SetValue(newWidth); |
|
||||||
} |
|
||||||
if (newHeight != GetHeight(item.View)) { |
|
||||||
item.Properties.GetProperty(FrameworkElement.HeightProperty).SetValue(newHeight); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,57 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Input; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.OutlineView |
|
||||||
{ |
|
||||||
public class DragListener |
|
||||||
{ |
|
||||||
public DragListener(FrameworkElement target) |
|
||||||
{ |
|
||||||
this.target = target; |
|
||||||
target.AddHandler(Mouse.MouseDownEvent, new MouseButtonEventHandler(MouseButtonDown), true); |
|
||||||
target.PreviewMouseMove += MouseMove; |
|
||||||
target.PreviewMouseLeftButtonUp += MouseLeftButtonUp; |
|
||||||
} |
|
||||||
|
|
||||||
public event MouseButtonEventHandler DragStarted; |
|
||||||
|
|
||||||
FrameworkElement target; |
|
||||||
Point startPoint; |
|
||||||
bool ready; |
|
||||||
MouseButtonEventArgs args; |
|
||||||
|
|
||||||
void MouseButtonDown(object sender, MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
if (e.ChangedButton == MouseButton.Left && Mouse.Captured == null) { |
|
||||||
ready = true; |
|
||||||
startPoint = e.GetPosition(target); |
|
||||||
args = e; |
|
||||||
target.CaptureMouse(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void MouseMove(object sender, MouseEventArgs e) |
|
||||||
{ |
|
||||||
if (ready) { |
|
||||||
var currentPoint = e.GetPosition(target); |
|
||||||
if (Math.Abs(currentPoint.X - startPoint.X) >= SystemParameters.MinimumHorizontalDragDistance || |
|
||||||
Math.Abs(currentPoint.Y - startPoint.Y) >= SystemParameters.MinimumVerticalDragDistance) { |
|
||||||
ready = false; |
|
||||||
if (DragStarted != null) { |
|
||||||
DragStarted(this, args); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void MouseLeftButtonUp(object sender, MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
ready = false; |
|
||||||
target.ReleaseMouseCapture(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,326 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Collections.Specialized; |
|
||||||
using System.Collections; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.OutlineView |
|
||||||
{ |
|
||||||
// limitations:
|
|
||||||
// - Do not use ItemsSource (use Root)
|
|
||||||
// - Do not use Items (use Root)
|
|
||||||
public class DragTreeView : TreeView |
|
||||||
{ |
|
||||||
static DragTreeView() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(DragTreeView), |
|
||||||
new FrameworkPropertyMetadata(typeof(DragTreeView))); |
|
||||||
} |
|
||||||
|
|
||||||
public DragTreeView() |
|
||||||
{ |
|
||||||
AllowDrop = true; |
|
||||||
new DragListener(this).DragStarted += new MouseButtonEventHandler(DragTreeView_DragStarted); |
|
||||||
} |
|
||||||
|
|
||||||
DragTreeViewItem dropTarget; |
|
||||||
DragTreeViewItem treeItem; |
|
||||||
DragTreeViewItem dropAfter; |
|
||||||
int part; |
|
||||||
bool dropInside; |
|
||||||
bool dropCopy; |
|
||||||
bool canDrop; |
|
||||||
|
|
||||||
Border insertLine; |
|
||||||
|
|
||||||
public static readonly DependencyProperty RootProperty = |
|
||||||
DependencyProperty.Register("Root", typeof(object), typeof(DragTreeView)); |
|
||||||
|
|
||||||
public object Root { |
|
||||||
get { return (object)GetValue(RootProperty); } |
|
||||||
set { SetValue(RootProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
//public object[] SelectedItems
|
|
||||||
//{
|
|
||||||
// get { return Selection.Select(item => item.DataContext).ToArray(); }
|
|
||||||
//}
|
|
||||||
|
|
||||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
base.OnPropertyChanged(e); |
|
||||||
if (e.Property == RootProperty) { |
|
||||||
ItemsSource = new[] { Root }; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void DragTreeView_DragStarted(object sender, MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
DragDrop.DoDragDrop(this, this, DragDropEffects.All); |
|
||||||
} |
|
||||||
|
|
||||||
public override void OnApplyTemplate() |
|
||||||
{ |
|
||||||
base.OnApplyTemplate(); |
|
||||||
insertLine = (Border)Template.FindName("PART_InsertLine", this); |
|
||||||
} |
|
||||||
|
|
||||||
protected override DependencyObject GetContainerForItemOverride() |
|
||||||
{ |
|
||||||
return new DragTreeViewItem(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override bool IsItemItsOwnContainerOverride(object item) |
|
||||||
{ |
|
||||||
return item is DragTreeViewItem; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnDragEnter(DragEventArgs e) |
|
||||||
{ |
|
||||||
ProcessDrag(e); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnDragOver(DragEventArgs e) |
|
||||||
{ |
|
||||||
ProcessDrag(e); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnDrop(DragEventArgs e) |
|
||||||
{ |
|
||||||
ProcessDrop(e); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnDragLeave(DragEventArgs e) |
|
||||||
{ |
|
||||||
HideDropMarker(); |
|
||||||
} |
|
||||||
|
|
||||||
void PrepareDropInfo(DragEventArgs e) |
|
||||||
{ |
|
||||||
dropTarget = null; |
|
||||||
dropAfter = null; |
|
||||||
treeItem = (e.OriginalSource as DependencyObject).FindAncestor<DragTreeViewItem>(); |
|
||||||
|
|
||||||
if (treeItem != null) { |
|
||||||
var parent = ItemsControl.ItemsControlFromItemContainer(treeItem) as DragTreeViewItem; |
|
||||||
ContentPresenter header = treeItem.HeaderPresenter; |
|
||||||
Point p = e.GetPosition(header); |
|
||||||
part = (int)(p.Y / (header.ActualHeight / 3)); |
|
||||||
dropCopy = Keyboard.IsKeyDown(Key.LeftCtrl); |
|
||||||
dropInside = false; |
|
||||||
|
|
||||||
if (part == 1 || parent == null) { |
|
||||||
dropTarget = treeItem; |
|
||||||
dropInside = true; |
|
||||||
if (treeItem.Items.Count > 0) { |
|
||||||
dropAfter = treeItem.ItemContainerGenerator.ContainerFromIndex(treeItem.Items.Count - 1) as DragTreeViewItem; |
|
||||||
} |
|
||||||
} |
|
||||||
else if (part == 0) { |
|
||||||
dropTarget = parent; |
|
||||||
var index = dropTarget.ItemContainerGenerator.IndexFromContainer(treeItem); |
|
||||||
if (index > 0) { |
|
||||||
dropAfter = dropTarget.ItemContainerGenerator.ContainerFromIndex(index - 1) as DragTreeViewItem; |
|
||||||
} |
|
||||||
} |
|
||||||
else { |
|
||||||
dropTarget = parent; |
|
||||||
dropAfter = treeItem; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void ProcessDrag(DragEventArgs e) |
|
||||||
{ |
|
||||||
e.Effects = DragDropEffects.None; |
|
||||||
e.Handled = true; |
|
||||||
canDrop = false; |
|
||||||
|
|
||||||
if (e.Data.GetData(GetType()) != this) return; |
|
||||||
|
|
||||||
HideDropMarker(); |
|
||||||
PrepareDropInfo(e); |
|
||||||
|
|
||||||
if (dropTarget != null && CanInsertInternal()) { |
|
||||||
canDrop = true; |
|
||||||
e.Effects = dropCopy ? DragDropEffects.Copy : DragDropEffects.Move; |
|
||||||
DrawDropMarker(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void ProcessDrop(DragEventArgs e) |
|
||||||
{ |
|
||||||
HideDropMarker(); |
|
||||||
|
|
||||||
if (canDrop) { |
|
||||||
InsertInternal(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void DrawDropMarker() |
|
||||||
{ |
|
||||||
if (dropInside) { |
|
||||||
dropTarget.IsDragHover = true; |
|
||||||
} |
|
||||||
else { |
|
||||||
var header = treeItem.HeaderPresenter; |
|
||||||
var p = header.TransformToVisual(this).Transform( |
|
||||||
new Point(0, part == 0 ? 0 : header.ActualHeight)); |
|
||||||
|
|
||||||
insertLine.Visibility = Visibility.Visible; |
|
||||||
insertLine.Margin = new Thickness(p.X, p.Y, 0, 0); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void HideDropMarker() |
|
||||||
{ |
|
||||||
insertLine.Visibility = Visibility.Collapsed; |
|
||||||
if (dropTarget != null) { |
|
||||||
dropTarget.IsDragHover = false; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
internal HashSet<DragTreeViewItem> Selection = new HashSet<DragTreeViewItem>(); |
|
||||||
DragTreeViewItem upSelection; |
|
||||||
|
|
||||||
internal void ItemMouseDown(DragTreeViewItem item) |
|
||||||
{ |
|
||||||
upSelection = null; |
|
||||||
bool control = Keyboard.IsKeyDown(Key.LeftCtrl); |
|
||||||
|
|
||||||
if (Selection.Contains(item)) { |
|
||||||
if (control) { |
|
||||||
Unselect(item); |
|
||||||
} |
|
||||||
else { |
|
||||||
upSelection = item; |
|
||||||
} |
|
||||||
} |
|
||||||
else { |
|
||||||
if (control) { |
|
||||||
Select(item); |
|
||||||
} |
|
||||||
else { |
|
||||||
SelectOnly(item); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
internal void ItemMouseUp(DragTreeViewItem item) |
|
||||||
{ |
|
||||||
if (upSelection == item) { |
|
||||||
SelectOnly(item); |
|
||||||
} |
|
||||||
upSelection = null; |
|
||||||
} |
|
||||||
|
|
||||||
internal void ItemAttached(DragTreeViewItem item) |
|
||||||
{ |
|
||||||
if (item.IsSelected) Selection.Add(item); |
|
||||||
} |
|
||||||
|
|
||||||
internal void ItemDetached(DragTreeViewItem item) |
|
||||||
{ |
|
||||||
if (item.IsSelected) Selection.Remove(item); |
|
||||||
} |
|
||||||
|
|
||||||
internal void ItemIsSelectedChanged(DragTreeViewItem item) |
|
||||||
{ |
|
||||||
if (item.IsSelected) { |
|
||||||
Selection.Add(item); |
|
||||||
} |
|
||||||
else { |
|
||||||
Selection.Remove(item); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void Select(DragTreeViewItem item) |
|
||||||
{ |
|
||||||
Selection.Add(item); |
|
||||||
item.IsSelected = true; |
|
||||||
OnSelectionChanged(); |
|
||||||
} |
|
||||||
|
|
||||||
void Unselect(DragTreeViewItem item) |
|
||||||
{ |
|
||||||
Selection.Remove(item); |
|
||||||
item.IsSelected = false; |
|
||||||
OnSelectionChanged(); |
|
||||||
} |
|
||||||
|
|
||||||
void SelectOnly(DragTreeViewItem item) |
|
||||||
{ |
|
||||||
ClearSelection(); |
|
||||||
Select(item); |
|
||||||
OnSelectionChanged(); |
|
||||||
} |
|
||||||
|
|
||||||
void ClearSelection() |
|
||||||
{ |
|
||||||
foreach (var treeItem in Selection.ToArray()) { |
|
||||||
treeItem.IsSelected = false; |
|
||||||
} |
|
||||||
Selection.Clear(); |
|
||||||
OnSelectionChanged(); |
|
||||||
} |
|
||||||
|
|
||||||
void OnSelectionChanged() |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
bool CanInsertInternal() |
|
||||||
{ |
|
||||||
if (!dropCopy) { |
|
||||||
var item = dropTarget; |
|
||||||
while (true) { |
|
||||||
if (Selection.Contains(item)) return false; |
|
||||||
item = ItemsControl.ItemsControlFromItemContainer(item) as DragTreeViewItem; |
|
||||||
if (item == null) break; |
|
||||||
} |
|
||||||
|
|
||||||
if (Selection.Contains(dropAfter)) return false; |
|
||||||
} |
|
||||||
|
|
||||||
return CanInsert(dropTarget, Selection.ToArray(), dropAfter, dropCopy); |
|
||||||
} |
|
||||||
|
|
||||||
void InsertInternal() |
|
||||||
{ |
|
||||||
var selection = Selection.ToArray(); |
|
||||||
|
|
||||||
if (!dropCopy) { |
|
||||||
foreach (var item in Selection.ToArray()) { |
|
||||||
var parent = ItemsControl.ItemsControlFromItemContainer(item) as DragTreeViewItem; |
|
||||||
//TODO
|
|
||||||
if (parent != null) { |
|
||||||
Remove(parent, item); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
Insert(dropTarget, selection, dropAfter, dropCopy); |
|
||||||
} |
|
||||||
|
|
||||||
protected virtual bool CanInsert(DragTreeViewItem target, DragTreeViewItem[] items, DragTreeViewItem after, bool copy) |
|
||||||
{ |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
protected virtual void Insert(DragTreeViewItem target, DragTreeViewItem[] items, DragTreeViewItem after, bool copy) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
protected virtual void Remove(DragTreeViewItem target, DragTreeViewItem item) |
|
||||||
{ |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,119 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.OutlineView |
|
||||||
{ |
|
||||||
public class DragTreeViewItem : TreeViewItem |
|
||||||
{ |
|
||||||
static DragTreeViewItem() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(DragTreeViewItem), |
|
||||||
new FrameworkPropertyMetadata(typeof(DragTreeViewItem))); |
|
||||||
} |
|
||||||
|
|
||||||
public DragTreeViewItem() |
|
||||||
{ |
|
||||||
Loaded += new RoutedEventHandler(DragTreeViewItem_Loaded); |
|
||||||
Unloaded += new RoutedEventHandler(DragTreeViewItem_Unloaded); |
|
||||||
} |
|
||||||
|
|
||||||
void DragTreeViewItem_Loaded(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
ParentTree = this.FindAncestor<DragTreeView>(); |
|
||||||
if (ParentTree != null) { |
|
||||||
ParentTree.ItemAttached(this); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void DragTreeViewItem_Unloaded(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
if (ParentTree != null) { |
|
||||||
ParentTree.ItemDetached(this); |
|
||||||
} |
|
||||||
ParentTree = null; |
|
||||||
} |
|
||||||
|
|
||||||
public new static readonly DependencyProperty IsSelectedProperty = |
|
||||||
Selector.IsSelectedProperty.AddOwner(typeof(DragTreeViewItem)); |
|
||||||
|
|
||||||
public new bool IsSelected { |
|
||||||
get { return (bool)GetValue(IsSelectedProperty); } |
|
||||||
set { SetValue(IsSelectedProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty IsDragHoverProperty = |
|
||||||
DependencyProperty.Register("IsDragHover", typeof(bool), typeof(DragTreeViewItem)); |
|
||||||
|
|
||||||
public bool IsDragHover { |
|
||||||
get { return (bool)GetValue(IsDragHoverProperty); } |
|
||||||
set { SetValue(IsDragHoverProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
internal ContentPresenter HeaderPresenter { |
|
||||||
get { return (ContentPresenter)Template.FindName("PART_Header", this); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty LevelProperty = |
|
||||||
DependencyProperty.Register("Level", typeof(int), typeof(DragTreeViewItem)); |
|
||||||
|
|
||||||
public int Level { |
|
||||||
get { return (int)GetValue(LevelProperty); } |
|
||||||
set { SetValue(LevelProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public DragTreeView ParentTree { get; private set; } |
|
||||||
|
|
||||||
protected override void OnVisualParentChanged(DependencyObject oldParent) |
|
||||||
{ |
|
||||||
base.OnVisualParentChanged(oldParent); |
|
||||||
|
|
||||||
var parentItem = ItemsControl.ItemsControlFromItemContainer(this) as DragTreeViewItem; |
|
||||||
if (parentItem != null) Level = parentItem.Level + 1; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
base.OnPropertyChanged(e); |
|
||||||
if (e.Property == IsSelectedProperty) { |
|
||||||
if (ParentTree != null) { |
|
||||||
ParentTree.ItemIsSelectedChanged(this); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override DependencyObject GetContainerForItemOverride() |
|
||||||
{ |
|
||||||
return new DragTreeViewItem(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override bool IsItemItsOwnContainerOverride(object item) |
|
||||||
{ |
|
||||||
return item is DragTreeViewItem; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
base.OnMouseLeftButtonDown(e); |
|
||||||
if (e.Source is ToggleButton || e.Source is ItemsPresenter) return; |
|
||||||
ParentTree.ItemMouseDown(this); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
base.OnMouseLeftButtonUp(e); |
|
||||||
ParentTree.ItemMouseUp(this); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,35 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.OutlineView |
|
||||||
{ |
|
||||||
public class IconItem : Control |
|
||||||
{ |
|
||||||
static IconItem() |
|
||||||
{ |
|
||||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(IconItem), |
|
||||||
new FrameworkPropertyMetadata(typeof(IconItem))); |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty IconProperty = |
|
||||||
DependencyProperty.Register("Icon", typeof(ImageSource), typeof(IconItem)); |
|
||||||
|
|
||||||
public ImageSource Icon { |
|
||||||
get { return (ImageSource)GetValue(IconProperty); } |
|
||||||
set { SetValue(IconProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty TextProperty = |
|
||||||
DependencyProperty.Register("Text", typeof(string), typeof(IconItem)); |
|
||||||
|
|
||||||
public string Text { |
|
||||||
get { return (string)GetValue(TextProperty); } |
|
||||||
set { SetValue(TextProperty, value); } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,28 +0,0 @@ |
|||||||
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.OutlineView.Outline" |
|
||||||
x:Name="root" |
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:Default="clr-namespace:ICSharpCode.WpfDesign.Designer.OutlineView"> |
|
||||||
|
|
||||||
<UserControl.Resources> |
|
||||||
|
|
||||||
<HierarchicalDataTemplate DataType="{x:Type Default:OutlineNode}" |
|
||||||
ItemsSource="{Binding Children}"> |
|
||||||
<Default:IconItem Icon="../Images/Tag.png" |
|
||||||
Text="{Binding Name}" /> |
|
||||||
</HierarchicalDataTemplate> |
|
||||||
|
|
||||||
</UserControl.Resources> |
|
||||||
|
|
||||||
<Default:OutlineTreeView Root="{Binding Root, ElementName=root}"> |
|
||||||
<ItemsControl.ItemContainerStyle> |
|
||||||
<Style TargetType="{x:Type Default:DragTreeViewItem}"> |
|
||||||
<Setter Property="IsSelected" |
|
||||||
Value="{Binding IsSelected}" /> |
|
||||||
<Setter Property="IsExpanded" |
|
||||||
Value="{Binding IsExpanded, Mode=TwoWay}" /> |
|
||||||
</Style> |
|
||||||
</ItemsControl.ItemContainerStyle> |
|
||||||
</Default:OutlineTreeView> |
|
||||||
|
|
||||||
</UserControl> |
|
||||||
@ -1,32 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.OutlineView |
|
||||||
{ |
|
||||||
public partial class Outline |
|
||||||
{ |
|
||||||
public Outline() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty RootProperty = |
|
||||||
DependencyProperty.Register("Root", typeof(OutlineNode), typeof(Outline)); |
|
||||||
|
|
||||||
public OutlineNode Root { |
|
||||||
get { return (OutlineNode)GetValue(RootProperty); } |
|
||||||
set { SetValue(RootProperty, value); } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,191 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.ComponentModel; |
|
||||||
using ICSharpCode.WpfDesign; |
|
||||||
using System.Collections.ObjectModel; |
|
||||||
using System.Collections; |
|
||||||
using ICSharpCode.WpfDesign.Designer; |
|
||||||
using ICSharpCode.WpfDesign.XamlDom; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.OutlineView |
|
||||||
{ |
|
||||||
public class OutlineNode : INotifyPropertyChanged |
|
||||||
{ |
|
||||||
public static OutlineNode Create(DesignItem designItem) |
|
||||||
{ |
|
||||||
OutlineNode node; |
|
||||||
if (!outlineNodes.TryGetValue(designItem, out node)) { |
|
||||||
node = new OutlineNode(designItem); |
|
||||||
outlineNodes[designItem] = node; |
|
||||||
} |
|
||||||
return node; |
|
||||||
} |
|
||||||
|
|
||||||
//TODO: Reset with DesignContext
|
|
||||||
static Dictionary<DesignItem, OutlineNode> outlineNodes = new Dictionary<DesignItem, OutlineNode>(); |
|
||||||
|
|
||||||
OutlineNode(DesignItem designItem) |
|
||||||
{ |
|
||||||
DesignItem = designItem; |
|
||||||
UpdateChildren(); |
|
||||||
|
|
||||||
//TODO
|
|
||||||
DesignItem.NameChanged += new EventHandler(DesignItem_NameChanged); |
|
||||||
DesignItem.PropertyChanged += new PropertyChangedEventHandler(DesignItem_PropertyChanged); |
|
||||||
SelectionService.SelectionChanged += new EventHandler<DesignItemCollectionEventArgs>(Selection_SelectionChanged); |
|
||||||
} |
|
||||||
|
|
||||||
public DesignItem DesignItem { get; private set; } |
|
||||||
|
|
||||||
public ISelectionService SelectionService { |
|
||||||
get { return DesignItem.Services.Selection; } |
|
||||||
} |
|
||||||
|
|
||||||
bool isExpanded = true; |
|
||||||
|
|
||||||
public bool IsExpanded { |
|
||||||
get { |
|
||||||
return isExpanded; |
|
||||||
} |
|
||||||
set { |
|
||||||
isExpanded = value; |
|
||||||
RaisePropertyChanged("IsExpanded"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool isSelected; |
|
||||||
|
|
||||||
public bool IsSelected { |
|
||||||
get { |
|
||||||
return isSelected; |
|
||||||
} |
|
||||||
set { |
|
||||||
if (isSelected != value) { |
|
||||||
isSelected = value; |
|
||||||
SelectionService.SetSelectedComponents(new[] { DesignItem }, |
|
||||||
value ? SelectionTypes.Add : SelectionTypes.Remove); |
|
||||||
RaisePropertyChanged("IsSelected"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
ObservableCollection<OutlineNode> children = new ObservableCollection<OutlineNode>(); |
|
||||||
|
|
||||||
public ObservableCollection<OutlineNode> Children { |
|
||||||
get { return children; } |
|
||||||
} |
|
||||||
|
|
||||||
public string Name { |
|
||||||
get { |
|
||||||
if (string.IsNullOrEmpty(DesignItem.Name)) { |
|
||||||
return DesignItem.ComponentType.Name; |
|
||||||
} |
|
||||||
return DesignItem.ComponentType.Name + " (" + DesignItem.Name + ")"; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void Selection_SelectionChanged(object sender, DesignItemCollectionEventArgs e) |
|
||||||
{ |
|
||||||
IsSelected = DesignItem.Services.Selection.IsComponentSelected(DesignItem); |
|
||||||
} |
|
||||||
|
|
||||||
void DesignItem_NameChanged(object sender, EventArgs e) |
|
||||||
{ |
|
||||||
RaisePropertyChanged("Name"); |
|
||||||
} |
|
||||||
|
|
||||||
void DesignItem_PropertyChanged(object sender, PropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
if (e.PropertyName == DesignItem.ContentPropertyName) { |
|
||||||
UpdateChildren(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void UpdateChildren() |
|
||||||
{ |
|
||||||
Children.Clear(); |
|
||||||
|
|
||||||
if (DesignItem.ContentPropertyName != null) { |
|
||||||
var content = DesignItem.ContentProperty; |
|
||||||
if (content.IsCollection) { |
|
||||||
UpdateChildrenCore(content.CollectionElements); |
|
||||||
} |
|
||||||
else { |
|
||||||
if (content.Value != null) { |
|
||||||
UpdateChildrenCore(new[] { content.Value }); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void UpdateChildrenCore(IEnumerable<DesignItem> items) |
|
||||||
{ |
|
||||||
foreach (var item in items) { |
|
||||||
if (ModelTools.CanSelectComponent(item)) { |
|
||||||
var node = OutlineNode.Create(item); |
|
||||||
Children.Add(node); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// TODO: Outline and IPlacementBehavior must use the same logic (put it inside DesignItem)
|
|
||||||
public bool CanInsert(IEnumerable<OutlineNode> nodes, OutlineNode after, bool copy) |
|
||||||
{ |
|
||||||
if (DesignItem.ContentPropertyName == null) return false; |
|
||||||
|
|
||||||
if (DesignItem.ContentProperty.IsCollection) { |
|
||||||
foreach (var node in nodes) { |
|
||||||
if (!CollectionSupport.CanCollectionAdd(DesignItem.ContentProperty.ReturnType, |
|
||||||
node.DesignItem.ComponentType)) { |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
return true; |
|
||||||
} |
|
||||||
else { |
|
||||||
return after == null && nodes.Count() == 1 && |
|
||||||
DesignItem.ContentProperty.DeclaringType.IsAssignableFrom( |
|
||||||
nodes.First().DesignItem.ComponentType); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void Insert(IEnumerable<OutlineNode> nodes, OutlineNode after, bool copy) |
|
||||||
{ |
|
||||||
if (copy) { |
|
||||||
nodes = nodes.Select(n => OutlineNode.Create(n.DesignItem.Clone())); |
|
||||||
} |
|
||||||
else { |
|
||||||
foreach (var node in nodes) { |
|
||||||
node.DesignItem.Remove(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
var index = after == null ? 0 : Children.IndexOf(after) + 1; |
|
||||||
|
|
||||||
var content = DesignItem.ContentProperty; |
|
||||||
if (content.IsCollection) { |
|
||||||
foreach (var node in nodes) { |
|
||||||
content.CollectionElements.Insert(index++, node.DesignItem); |
|
||||||
} |
|
||||||
} |
|
||||||
else { |
|
||||||
content.SetValue(nodes.First().DesignItem); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#region INotifyPropertyChanged Members
|
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged; |
|
||||||
|
|
||||||
void RaisePropertyChanged(string name) |
|
||||||
{ |
|
||||||
if (PropertyChanged != null) { |
|
||||||
PropertyChanged(this, new PropertyChangedEventArgs(name)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#endregion
|
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,22 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.OutlineView |
|
||||||
{ |
|
||||||
public class OutlineTreeView : DragTreeView |
|
||||||
{ |
|
||||||
protected override bool CanInsert(DragTreeViewItem target, DragTreeViewItem[] items, DragTreeViewItem after, bool copy) |
|
||||||
{ |
|
||||||
return (target.DataContext as OutlineNode).CanInsert(items.Select(t => t.DataContext as OutlineNode), |
|
||||||
after == null ? null : after.DataContext as OutlineNode, copy); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void Insert(DragTreeViewItem target, DragTreeViewItem[] items, DragTreeViewItem after, bool copy) |
|
||||||
{ |
|
||||||
(target.DataContext as OutlineNode).Insert(items.Select(t => t.DataContext as OutlineNode), |
|
||||||
after == null ? null : after.DataContext as OutlineNode, copy); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,151 +0,0 @@ |
|||||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:Default="clr-namespace:ICSharpCode.WpfDesign.Designer.OutlineView" |
|
||||||
xmlns:Converters="clr-namespace:ICSharpCode.WpfDesign.Designer.Converters" |
|
||||||
> |
|
||||||
<Converters:LevelConverter x:Key="LevelConverter" /> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Default:IconItem}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Default:IconItem}"> |
|
||||||
<StackPanel Orientation="Horizontal"> |
|
||||||
<Image Source="{TemplateBinding Icon}" |
|
||||||
Stretch="None" /> |
|
||||||
<TextBlock Text="{TemplateBinding Text}" |
|
||||||
VerticalAlignment="Center" |
|
||||||
Margin="5 0 0 0" /> |
|
||||||
</StackPanel> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style x:Key="ExpandButtonStyle" |
|
||||||
TargetType="ToggleButton"> |
|
||||||
<Setter Property="Focusable" |
|
||||||
Value="False" /> |
|
||||||
<Setter Property="ClickMode" |
|
||||||
Value="Press" /> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="ToggleButton"> |
|
||||||
<Border Background="Transparent"> |
|
||||||
<Border Width="9" |
|
||||||
Height="9" |
|
||||||
SnapsToDevicePixels="true" |
|
||||||
BorderBrush="#FF7898B5" |
|
||||||
BorderThickness="1" |
|
||||||
CornerRadius="1"> |
|
||||||
<Border.Background> |
|
||||||
<LinearGradientBrush EndPoint="1,1" |
|
||||||
StartPoint="0,0"> |
|
||||||
<GradientStop Color="White" |
|
||||||
Offset=".2" /> |
|
||||||
<GradientStop Color="#FFC0B7A6" |
|
||||||
Offset="1" /> |
|
||||||
</LinearGradientBrush> |
|
||||||
</Border.Background> |
|
||||||
<Path Margin="1,1,1,1" |
|
||||||
x:Name="ExpandPath" |
|
||||||
Fill="Black" |
|
||||||
Data="M 0 2 L 0 3 L 2 3 L 2 5 L 3 5 L 3 3 L 5 3 L 5 2 L 3 2 L 3 0 L 2 0 L 2 2 Z" /> |
|
||||||
</Border> |
|
||||||
</Border> |
|
||||||
<ControlTemplate.Triggers> |
|
||||||
<Trigger Property="IsChecked" |
|
||||||
Value="True"> |
|
||||||
<Setter Property="Data" |
|
||||||
TargetName="ExpandPath" |
|
||||||
Value="M 0 2 L 0 3 L 5 3 L 5 2 Z" /> |
|
||||||
</Trigger> |
|
||||||
</ControlTemplate.Triggers> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Brush x:Key="InsertBrush">#FFC73C</Brush> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Default:DragTreeView}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Default:DragTreeView}"> |
|
||||||
<Grid Background="White"> |
|
||||||
<ScrollViewer HorizontalScrollBarVisibility="Auto" |
|
||||||
VerticalScrollBarVisibility="Auto"> |
|
||||||
<ItemsPresenter /> |
|
||||||
</ScrollViewer> |
|
||||||
<Border x:Name="PART_InsertLine" |
|
||||||
Background="{StaticResource InsertBrush}" |
|
||||||
Height="2" |
|
||||||
Width="50" |
|
||||||
HorizontalAlignment="Left" |
|
||||||
VerticalAlignment="Top" |
|
||||||
Visibility="Collapsed" |
|
||||||
IsHitTestVisible="False" /> |
|
||||||
</Grid> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type Default:DragTreeViewItem}"> |
|
||||||
<Setter Property="Foreground" |
|
||||||
Value="{x:Static SystemColors.ControlTextBrush}" /> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type Default:DragTreeViewItem}"> |
|
||||||
|
|
||||||
<DockPanel Background="White"> |
|
||||||
<DockPanel x:Name="bg" |
|
||||||
DockPanel.Dock="Top" |
|
||||||
Background="{TemplateBinding Background}"> |
|
||||||
<ToggleButton x:Name="expandButton" |
|
||||||
Style="{StaticResource ExpandButtonStyle}" |
|
||||||
DockPanel.Dock="Left" |
|
||||||
Margin="{TemplateBinding Level, Converter={StaticResource LevelConverter}}" |
|
||||||
IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" /> |
|
||||||
<Border x:Name="contentBorder" |
|
||||||
HorizontalAlignment="Left"> |
|
||||||
<ContentPresenter x:Name="PART_Header" |
|
||||||
ContentSource="Header" /> |
|
||||||
</Border> |
|
||||||
</DockPanel> |
|
||||||
<ItemsPresenter x:Name="itemsHost" /> |
|
||||||
</DockPanel> |
|
||||||
|
|
||||||
<ControlTemplate.Triggers> |
|
||||||
<Trigger Property="IsExpanded" |
|
||||||
Value="False"> |
|
||||||
<Setter TargetName="itemsHost" |
|
||||||
Property="Visibility" |
|
||||||
Value="Collapsed" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="HasItems" |
|
||||||
Value="False"> |
|
||||||
<Setter TargetName="expandButton" |
|
||||||
Property="Visibility" |
|
||||||
Value="Hidden" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="IsSelected" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="bg" |
|
||||||
Property="Background" |
|
||||||
Value="{x:Static SystemColors.HighlightBrush}" /> |
|
||||||
<Setter Property="Foreground" |
|
||||||
Value="{x:Static SystemColors.HighlightTextBrush}" /> |
|
||||||
</Trigger> |
|
||||||
<Trigger Property="IsDragHover" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="contentBorder" |
|
||||||
Property="Background" |
|
||||||
Value="{StaticResource InsertBrush}" /> |
|
||||||
</Trigger> |
|
||||||
</ControlTemplate.Triggers> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
</ResourceDictionary> |
|
||||||
@ -1,7 +0,0 @@ |
|||||||
<CheckBox |
|
||||||
x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BoolEditor" |
|
||||||
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
IsChecked="{Binding Value}" |
|
||||||
> |
|
||||||
</CheckBox> |
|
||||||
@ -1,26 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using ICSharpCode.WpfDesign.PropertyGrid; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors |
|
||||||
{ |
|
||||||
[TypeEditor(typeof(bool))] |
|
||||||
public partial class BoolEditor |
|
||||||
{ |
|
||||||
public BoolEditor() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,207 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.ComponentModel; |
|
||||||
using ICSharpCode.WpfDesign.PropertyGrid; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Reflection; |
|
||||||
using System.Windows; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor |
|
||||||
{ |
|
||||||
public class BrushEditor : INotifyPropertyChanged |
|
||||||
{ |
|
||||||
public BrushEditor() |
|
||||||
{ |
|
||||||
GradientStopCollection stops = new GradientStopCollection(); |
|
||||||
stops.Add(new GradientStop(Colors.Black, 0)); |
|
||||||
stops.Add(new GradientStop(Colors.White, 1)); |
|
||||||
|
|
||||||
linearGradientBrush = new LinearGradientBrush(stops); |
|
||||||
linearGradientBrush.EndPoint = new Point(1, 0); |
|
||||||
radialGradientBrush = new RadialGradientBrush(stops); |
|
||||||
} |
|
||||||
|
|
||||||
public static BrushItem[] SystemBrushes = typeof(SystemColors) |
|
||||||
.GetProperties(BindingFlags.Static | BindingFlags.Public) |
|
||||||
.Where(p => p.PropertyType == typeof(SolidColorBrush)) |
|
||||||
.Select(p => new BrushItem() { Name = p.Name, Brush = (Brush)p.GetValue(null, null) }) |
|
||||||
.ToArray(); |
|
||||||
|
|
||||||
public static BrushItem[] SystemColors = typeof(SystemColors) |
|
||||||
.GetProperties(BindingFlags.Static | BindingFlags.Public) |
|
||||||
.Where(p => p.PropertyType == typeof(Color)) |
|
||||||
.Select(p => new BrushItem() |
|
||||||
{ |
|
||||||
Name = p.Name, |
|
||||||
Brush = new SolidColorBrush((Color)p.GetValue(null, null)) |
|
||||||
}) |
|
||||||
.ToArray(); |
|
||||||
|
|
||||||
SolidColorBrush solidColorBrush = new SolidColorBrush(Colors.White); |
|
||||||
LinearGradientBrush linearGradientBrush; |
|
||||||
RadialGradientBrush radialGradientBrush; |
|
||||||
|
|
||||||
PropertyNode property; |
|
||||||
|
|
||||||
public PropertyNode Property { |
|
||||||
get { |
|
||||||
return property; |
|
||||||
} |
|
||||||
set { |
|
||||||
property = value; |
|
||||||
if (property != null) { |
|
||||||
var f = property.Value as Freezable; |
|
||||||
if (f != null && f.IsFrozen) property.Value = f.Clone(); |
|
||||||
} |
|
||||||
DetermineCurrentKind(); |
|
||||||
RaisePropertyChanged("Property"); |
|
||||||
RaisePropertyChanged("Brush"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public Brush Brush { |
|
||||||
get { |
|
||||||
if (property != null) { |
|
||||||
return property.Value as Brush; |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
set { |
|
||||||
if (property != null && property.Value != value) { |
|
||||||
property.Value = value; |
|
||||||
DetermineCurrentKind(); |
|
||||||
RaisePropertyChanged("Brush"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void DetermineCurrentKind() |
|
||||||
{ |
|
||||||
if (Brush == null) { |
|
||||||
CurrentKind = BrushEditorKind.None; |
|
||||||
} |
|
||||||
else if (Brush is SolidColorBrush) { |
|
||||||
solidColorBrush = Brush as SolidColorBrush; |
|
||||||
CurrentKind = BrushEditorKind.Solid; |
|
||||||
} |
|
||||||
else if (Brush is LinearGradientBrush) { |
|
||||||
linearGradientBrush = Brush as LinearGradientBrush; |
|
||||||
radialGradientBrush.GradientStops = linearGradientBrush.GradientStops; |
|
||||||
CurrentKind = BrushEditorKind.Linear; |
|
||||||
} |
|
||||||
else if (Brush is RadialGradientBrush) { |
|
||||||
radialGradientBrush = Brush as RadialGradientBrush; |
|
||||||
linearGradientBrush.GradientStops = linearGradientBrush.GradientStops; |
|
||||||
CurrentKind = BrushEditorKind.Radial; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
BrushEditorKind currentKind; |
|
||||||
|
|
||||||
public BrushEditorKind CurrentKind { |
|
||||||
get { |
|
||||||
return currentKind; |
|
||||||
} |
|
||||||
set { |
|
||||||
currentKind = value; |
|
||||||
RaisePropertyChanged("CurrentKind"); |
|
||||||
|
|
||||||
switch (CurrentKind) { |
|
||||||
case BrushEditorKind.None: |
|
||||||
Brush = null; |
|
||||||
break; |
|
||||||
|
|
||||||
case BrushEditorKind.Solid: |
|
||||||
Brush = solidColorBrush; |
|
||||||
break; |
|
||||||
|
|
||||||
case BrushEditorKind.Linear: |
|
||||||
Brush = linearGradientBrush; |
|
||||||
break; |
|
||||||
|
|
||||||
case BrushEditorKind.Radial: |
|
||||||
Brush = radialGradientBrush; |
|
||||||
break; |
|
||||||
|
|
||||||
case BrushEditorKind.List: |
|
||||||
Brush = solidColorBrush; |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public double GradientAngle { |
|
||||||
get { |
|
||||||
var x = linearGradientBrush.EndPoint.X - linearGradientBrush.StartPoint.X; |
|
||||||
var y = linearGradientBrush.EndPoint.Y - linearGradientBrush.StartPoint.Y; |
|
||||||
return Vector.AngleBetween(new Vector(1, 0), new Vector(x, -y)); |
|
||||||
} |
|
||||||
set { |
|
||||||
var d = value * Math.PI / 180; |
|
||||||
var p = new Point(Math.Cos(d), -Math.Sin(d)); |
|
||||||
var k = 1 / Math.Max(Math.Abs(p.X), Math.Abs(p.Y)); |
|
||||||
p.X *= k; |
|
||||||
p.Y *= k; |
|
||||||
var p2 = new Point(-p.X, -p.Y); |
|
||||||
linearGradientBrush.StartPoint = new Point((p2.X + 1) / 2, (p2.Y + 1) / 2); |
|
||||||
linearGradientBrush.EndPoint = new Point((p.X + 1) / 2, (p.Y + 1) / 2); |
|
||||||
RaisePropertyChanged("GradientAngle"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<BrushItem> AvailableColors { |
|
||||||
get { return SystemColors; } |
|
||||||
} |
|
||||||
|
|
||||||
public IEnumerable<BrushItem> AvailableBrushes { |
|
||||||
get { return SystemBrushes; } |
|
||||||
} |
|
||||||
|
|
||||||
public void MakeGradientHorizontal() |
|
||||||
{ |
|
||||||
GradientAngle = 0; |
|
||||||
} |
|
||||||
|
|
||||||
public void MakeGradientVertical() |
|
||||||
{ |
|
||||||
GradientAngle = -90; |
|
||||||
} |
|
||||||
|
|
||||||
public void Commit() |
|
||||||
{ |
|
||||||
if (Brush != null) { |
|
||||||
Property.Value = Brush.Clone(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#region INotifyPropertyChanged Members
|
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged; |
|
||||||
|
|
||||||
void RaisePropertyChanged(string name) |
|
||||||
{ |
|
||||||
if (PropertyChanged != null) { |
|
||||||
PropertyChanged(this, new PropertyChangedEventArgs(name)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#endregion
|
|
||||||
} |
|
||||||
|
|
||||||
public enum BrushEditorKind |
|
||||||
{ |
|
||||||
None, |
|
||||||
Solid, |
|
||||||
Linear, |
|
||||||
Radial, |
|
||||||
List |
|
||||||
} |
|
||||||
|
|
||||||
public class BrushItem |
|
||||||
{ |
|
||||||
public string Name { get; set; } |
|
||||||
public Brush Brush { get; set; } |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,11 +0,0 @@ |
|||||||
<Popup x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor.BrushEditorPopup" |
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:BrushEditor="clr-namespace:ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor" |
|
||||||
Placement="Bottom" |
|
||||||
AllowsTransparency="True" |
|
||||||
SnapsToDevicePixels="True" |
|
||||||
StaysOpen="False"> |
|
||||||
<BrushEditor:BrushEditorView x:Name="BrushEditorView" |
|
||||||
x:FieldModifier="public" /> |
|
||||||
</Popup> |
|
||||||
@ -1,36 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Diagnostics; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor |
|
||||||
{ |
|
||||||
public partial class BrushEditorPopup |
|
||||||
{ |
|
||||||
public BrushEditorPopup() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnClosed(EventArgs e) |
|
||||||
{ |
|
||||||
base.OnClosed(e); |
|
||||||
BrushEditorView.BrushEditor.Commit(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnKeyDown(KeyEventArgs e) |
|
||||||
{ |
|
||||||
if (e.Key == Key.Escape) IsOpen = false; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,81 +0,0 @@ |
|||||||
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor.BrushEditorView" |
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:Designer="clr-namespace:ICSharpCode.WpfDesign.Designer" |
|
||||||
xmlns:Controls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls" |
|
||||||
xmlns:BrushEditor="clr-namespace:ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor" |
|
||||||
xmlns:Converters="clr-namespace:ICSharpCode.WpfDesign.Designer.Converters" |
|
||||||
xmlns:PropertyGrid="clr-namespace:ICSharpCode.WpfDesign.Designer.PropertyGrid" |
|
||||||
Width="395"> |
|
||||||
|
|
||||||
<UserControl.Resources> |
|
||||||
|
|
||||||
<DataTemplate DataType="{x:Type BrushEditor:BrushItem}"> |
|
||||||
<StackPanel Orientation="Horizontal"> |
|
||||||
<Border Background="{Binding Brush}" |
|
||||||
Width="30" |
|
||||||
Height="15" |
|
||||||
Margin="2" |
|
||||||
BorderThickness="1" |
|
||||||
BorderBrush="Black" /> |
|
||||||
<TextBlock Text="{Binding Name}" |
|
||||||
VerticalAlignment="Center" /> |
|
||||||
</StackPanel> |
|
||||||
</DataTemplate> |
|
||||||
|
|
||||||
</UserControl.Resources> |
|
||||||
|
|
||||||
<TabControl x:Name="tabControl" |
|
||||||
SelectedIndex="{Binding CurrentKind, Converter={x:Static Converters:IntFromEnumConverter.Instance}}"> |
|
||||||
<TabItem Header="None"> |
|
||||||
<Border Background="White" |
|
||||||
BorderThickness="1" |
|
||||||
BorderBrush="Black" |
|
||||||
HorizontalAlignment="Center" |
|
||||||
VerticalAlignment="Center"> |
|
||||||
<Line X1="0" |
|
||||||
Y1="40" |
|
||||||
X2="70" |
|
||||||
Y2="0" |
|
||||||
Stroke="Red" |
|
||||||
StrokeThickness="1" /> |
|
||||||
</Border> |
|
||||||
</TabItem> |
|
||||||
<TabItem Header="Solid"> |
|
||||||
<BrushEditor:SolidBrushEditor Color="{Binding Brush.Color}" /> |
|
||||||
</TabItem> |
|
||||||
<TabItem Header="Linear"> |
|
||||||
<DockPanel> |
|
||||||
<StackPanel DockPanel.Dock="Top" |
|
||||||
Orientation="Horizontal" |
|
||||||
Margin="5"> |
|
||||||
<TextBlock Text="Angle" |
|
||||||
VerticalAlignment="Center" /> |
|
||||||
<Controls:NumericUpDown Value="{Binding GradientAngle}" |
|
||||||
Minimum="-360" |
|
||||||
Maximum="360" |
|
||||||
Margin="5 0 0 0" |
|
||||||
Width="50" /> |
|
||||||
<Button Content="H" |
|
||||||
Command="{Designer:Call MakeGradientHorizontal}" |
|
||||||
Margin="5 0 0 0" |
|
||||||
Width="30" /> |
|
||||||
<Button Content="V" |
|
||||||
Command="{Designer:Call MakeGradientVertical}" |
|
||||||
Margin="5 0 0 0" |
|
||||||
Width="30" /> |
|
||||||
</StackPanel> |
|
||||||
<BrushEditor:GradientBrushEditor /> |
|
||||||
</DockPanel> |
|
||||||
</TabItem> |
|
||||||
<TabItem Header="Radial"> |
|
||||||
<BrushEditor:GradientBrushEditor /> |
|
||||||
</TabItem> |
|
||||||
<TabItem Header="Brush List"> |
|
||||||
<ListBox ItemsSource="{Binding AvailableBrushes}" |
|
||||||
SelectedValue="{Binding Brush.Color}" |
|
||||||
SelectedValuePath="Brush.Color" /> |
|
||||||
</TabItem> |
|
||||||
</TabControl> |
|
||||||
|
|
||||||
</UserControl> |
|
||||||
@ -1,51 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Diagnostics; |
|
||||||
using System.Globalization; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor |
|
||||||
{ |
|
||||||
public partial class BrushEditorView |
|
||||||
{ |
|
||||||
public BrushEditorView() |
|
||||||
{ |
|
||||||
BrushEditor = new BrushEditor(); |
|
||||||
DataContext = BrushEditor; |
|
||||||
|
|
||||||
InitializeComponent(); |
|
||||||
|
|
||||||
SetBinding(HeightProperty, new Binding("Brush") { |
|
||||||
Converter = HeightConverter.Instance |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
public BrushEditor BrushEditor { get; private set; } |
|
||||||
|
|
||||||
class HeightConverter : IValueConverter |
|
||||||
{ |
|
||||||
public static HeightConverter Instance = new HeightConverter(); |
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
if (value is GradientBrush) return double.NaN; |
|
||||||
return 315; |
|
||||||
} |
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
|
||||||
{ |
|
||||||
throw new NotImplementedException(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,13 +0,0 @@ |
|||||||
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor.BrushTypeEditor" |
|
||||||
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
|
||||||
<Border BorderThickness="1" |
|
||||||
BorderBrush="Black" |
|
||||||
Background="Transparent" |
|
||||||
HorizontalAlignment="Left" |
|
||||||
Cursor="Hand" |
|
||||||
Width="30" |
|
||||||
Height="16"> |
|
||||||
<Border Background="{Binding Value}" /> |
|
||||||
</Border> |
|
||||||
</UserControl> |
|
||||||
@ -1,36 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using ICSharpCode.WpfDesign.PropertyGrid; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor |
|
||||||
{ |
|
||||||
[TypeEditor(typeof(Brush))] |
|
||||||
public partial class BrushTypeEditor |
|
||||||
{ |
|
||||||
public BrushTypeEditor() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
} |
|
||||||
|
|
||||||
static BrushEditorPopup brushEditorPopup = new BrushEditorPopup(); |
|
||||||
|
|
||||||
protected override void OnMouseUp(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
brushEditorPopup.BrushEditorView.BrushEditor.Property = DataContext as PropertyNode; |
|
||||||
brushEditorPopup.PlacementTarget = this; |
|
||||||
brushEditorPopup.IsOpen = true; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,92 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor |
|
||||||
{ |
|
||||||
public static class ColorHelper |
|
||||||
{ |
|
||||||
public static Color ColorFromString(string s) |
|
||||||
{ |
|
||||||
if (string.IsNullOrEmpty(s)) { |
|
||||||
return Colors.White; |
|
||||||
} |
|
||||||
if (s[0] != '#') s = "#" + s; |
|
||||||
try { |
|
||||||
return (Color)ColorConverter.ConvertFromString(s); |
|
||||||
} |
|
||||||
catch { |
|
||||||
return Colors.White; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static string StringFromColor(Color c) |
|
||||||
{ |
|
||||||
return c.ToString().Substring(1); |
|
||||||
} |
|
||||||
|
|
||||||
public static Color ColorFromHsv(double h, double s, double v) |
|
||||||
{ |
|
||||||
double r, g, b; |
|
||||||
RgbFromHsv(h, s, v, out r, out g, out b); |
|
||||||
return Color.FromRgb((byte)(r * 255), (byte)(g * 255), (byte)(b * 255)); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
public static void HsvFromColor(Color c, out double h, out double s, out double v) |
|
||||||
{ |
|
||||||
HsvFromRgb(c.R / 255.0, c.G / 255.0, c.B / 255.0, out h, out s, out v); |
|
||||||
} |
|
||||||
|
|
||||||
// http://en.wikipedia.org/wiki/HSV_color_space
|
|
||||||
public static void HsvFromRgb(double r, double g, double b, out double h, out double s, out double v) |
|
||||||
{ |
|
||||||
var max = Math.Max(r, Math.Max(g, b)); |
|
||||||
var min = Math.Min(r, Math.Min(g, b)); |
|
||||||
|
|
||||||
if (max == min) { |
|
||||||
h = 0; |
|
||||||
} |
|
||||||
else if (max == r) { |
|
||||||
h = (60 * (g - b) / (max - min)) % 360; |
|
||||||
} |
|
||||||
else if (max == g) { |
|
||||||
h = 60 * (b - r) / (max - min) + 120; |
|
||||||
} |
|
||||||
else { |
|
||||||
h = 60 * (r - g) / (max - min) + 240; |
|
||||||
} |
|
||||||
|
|
||||||
if (max == 0) { |
|
||||||
s = 0; |
|
||||||
} |
|
||||||
else { |
|
||||||
s = 1 - min / max; |
|
||||||
} |
|
||||||
|
|
||||||
v = max; |
|
||||||
} |
|
||||||
|
|
||||||
// http://en.wikipedia.org/wiki/HSV_color_space
|
|
||||||
public static void RgbFromHsv(double h, double s, double v, out double r, out double g, out double b) |
|
||||||
{ |
|
||||||
h = h % 360; |
|
||||||
int hi = (int)(h / 60) % 6; |
|
||||||
var f = h / 60 - (int)(h / 60); |
|
||||||
var p = v * (1 - s); |
|
||||||
var q = v * (1 - f * s); |
|
||||||
var t = v * (1 - (1 - f) * s); |
|
||||||
|
|
||||||
switch (hi) { |
|
||||||
case 0: r = v; g = t; b = p; break; |
|
||||||
case 1: r = q; g = v; b = p; break; |
|
||||||
case 2: r = p; g = v; b = t; break; |
|
||||||
case 3: r = p; g = q; b = v; break; |
|
||||||
case 4: r = t; g = p; b = v; break; |
|
||||||
default: r = v; g = p; b = q; break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,233 +0,0 @@ |
|||||||
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor.ColorPicker" |
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:Controls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls" |
|
||||||
xmlns:BrushEditor="clr-namespace:ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor" |
|
||||||
x:Name="this" |
|
||||||
Padding="5" |
|
||||||
Width="373"> |
|
||||||
|
|
||||||
<UserControl.Resources> |
|
||||||
|
|
||||||
<DrawingBrush x:Key="ChessBrush" |
|
||||||
TileMode="Tile" |
|
||||||
ViewportUnits="Absolute" |
|
||||||
Viewport="0 0 9 9"> |
|
||||||
<DrawingBrush.Drawing> |
|
||||||
<DrawingGroup> |
|
||||||
<GeometryDrawing Brush="White"> |
|
||||||
<GeometryDrawing.Geometry> |
|
||||||
<RectangleGeometry Rect="0 0 2 2" /> |
|
||||||
</GeometryDrawing.Geometry> |
|
||||||
</GeometryDrawing> |
|
||||||
<GeometryDrawing Brush="Gray"> |
|
||||||
<GeometryDrawing.Geometry> |
|
||||||
<GeometryGroup> |
|
||||||
<RectangleGeometry Rect="0 0 1 1" /> |
|
||||||
<RectangleGeometry Rect="1 1 1 1" /> |
|
||||||
</GeometryGroup> |
|
||||||
</GeometryDrawing.Geometry> |
|
||||||
</GeometryDrawing> |
|
||||||
</DrawingGroup> |
|
||||||
</DrawingBrush.Drawing> |
|
||||||
</DrawingBrush> |
|
||||||
|
|
||||||
</UserControl.Resources> |
|
||||||
|
|
||||||
<DockPanel> |
|
||||||
|
|
||||||
<StackPanel VerticalAlignment="Top" |
|
||||||
DockPanel.Dock="Right" |
|
||||||
Margin="10 0 0 0"> |
|
||||||
|
|
||||||
<Border Background="{StaticResource ChessBrush}" |
|
||||||
HorizontalAlignment="Right" |
|
||||||
BorderBrush="Black" |
|
||||||
BorderThickness="1" |
|
||||||
Height="50" |
|
||||||
Width="70"> |
|
||||||
<Rectangle> |
|
||||||
<Rectangle.Fill> |
|
||||||
<SolidColorBrush Color="{Binding Color, ElementName=this}" /> |
|
||||||
</Rectangle.Fill> |
|
||||||
</Rectangle> |
|
||||||
</Border> |
|
||||||
|
|
||||||
<DockPanel Margin="0 3 0 0"> |
|
||||||
<BrushEditor:HexTextBox Text="{Binding Hex, ElementName=this, UpdateSourceTrigger=PropertyChanged}" |
|
||||||
Width="70" |
|
||||||
Margin="5 0 0 0" |
|
||||||
DockPanel.Dock="Right" /> |
|
||||||
<TextBlock Text="#" |
|
||||||
VerticalAlignment="Center" |
|
||||||
HorizontalAlignment="Right" /> |
|
||||||
</DockPanel> |
|
||||||
|
|
||||||
<DockPanel Margin="0 3 0 0"> |
|
||||||
<Controls:NumericUpDown Value="{Binding H, ElementName=this}" |
|
||||||
Maximum="360" |
|
||||||
Width="70" |
|
||||||
Margin="5 0 0 0" |
|
||||||
DockPanel.Dock="Right" /> |
|
||||||
<TextBlock Text="H" |
|
||||||
VerticalAlignment="Center" |
|
||||||
HorizontalAlignment="Right" /> |
|
||||||
</DockPanel> |
|
||||||
|
|
||||||
<DockPanel Margin="0 3 0 0"> |
|
||||||
<Controls:NumericUpDown Value="{Binding S, ElementName=this}" |
|
||||||
Width="70" |
|
||||||
Margin="5 0 0 0" |
|
||||||
DockPanel.Dock="Right" /> |
|
||||||
<TextBlock Text="S" |
|
||||||
VerticalAlignment="Center" |
|
||||||
HorizontalAlignment="Right" /> |
|
||||||
</DockPanel> |
|
||||||
|
|
||||||
<DockPanel Margin="0 3 0 0"> |
|
||||||
<Controls:NumericUpDown Value="{Binding V, ElementName=this}" |
|
||||||
Width="70" |
|
||||||
Margin="5 0 0 0" |
|
||||||
DockPanel.Dock="Right" /> |
|
||||||
<TextBlock Text="V" |
|
||||||
VerticalAlignment="Center" |
|
||||||
HorizontalAlignment="Right" /> |
|
||||||
</DockPanel> |
|
||||||
|
|
||||||
<DockPanel Margin="0 3 0 0"> |
|
||||||
<Controls:NumericUpDown Value="{Binding R, ElementName=this}" |
|
||||||
Maximum="255" |
|
||||||
Width="70" |
|
||||||
Margin="5 0 0 0" |
|
||||||
DockPanel.Dock="Right" /> |
|
||||||
<TextBlock Text="R" |
|
||||||
VerticalAlignment="Center" |
|
||||||
HorizontalAlignment="Right" /> |
|
||||||
</DockPanel> |
|
||||||
|
|
||||||
<DockPanel Margin="0 3 0 0"> |
|
||||||
<Controls:NumericUpDown Value="{Binding G, ElementName=this}" |
|
||||||
Maximum="255" |
|
||||||
Width="70" |
|
||||||
Margin="5 0 0 0" |
|
||||||
DockPanel.Dock="Right" /> |
|
||||||
<TextBlock Text="G" |
|
||||||
VerticalAlignment="Center" |
|
||||||
HorizontalAlignment="Right" /> |
|
||||||
</DockPanel> |
|
||||||
|
|
||||||
<DockPanel Margin="0 3 0 0"> |
|
||||||
<Controls:NumericUpDown Value="{Binding B, ElementName=this}" |
|
||||||
Maximum="255" |
|
||||||
Width="70" |
|
||||||
Margin="5 0 0 0" |
|
||||||
DockPanel.Dock="Right" /> |
|
||||||
<TextBlock Text="B" |
|
||||||
VerticalAlignment="Center" |
|
||||||
HorizontalAlignment="Right" /> |
|
||||||
</DockPanel> |
|
||||||
|
|
||||||
<DockPanel Margin="0 3 0 0"> |
|
||||||
<Controls:NumericUpDown Value="{Binding A, ElementName=this}" |
|
||||||
Maximum="255" |
|
||||||
Width="70" |
|
||||||
Margin="5 0 0 0" |
|
||||||
DockPanel.Dock="Right" /> |
|
||||||
<TextBlock Text="A" |
|
||||||
VerticalAlignment="Center" |
|
||||||
HorizontalAlignment="Right" /> |
|
||||||
</DockPanel> |
|
||||||
|
|
||||||
</StackPanel> |
|
||||||
|
|
||||||
<Border Margin="10 0 0 0" |
|
||||||
DockPanel.Dock="Right"> |
|
||||||
<BrushEditor:Picker Orientation="Vertical" |
|
||||||
Value="{Binding H, ElementName=this}" |
|
||||||
Minimum="360" |
|
||||||
Maximum="0" |
|
||||||
Marker="{Binding ElementName=arrows}" |
|
||||||
Width="20"> |
|
||||||
<Border Margin="0 -1"> |
|
||||||
<Border.Background> |
|
||||||
<LinearGradientBrush EndPoint="0 1"> |
|
||||||
<GradientStop Offset="0" |
|
||||||
Color="#F00" /> |
|
||||||
<GradientStop Offset="0.16" |
|
||||||
Color="#F0F" /> |
|
||||||
<GradientStop Offset="0.33" |
|
||||||
Color="#00F" /> |
|
||||||
<GradientStop Offset="0.5" |
|
||||||
Color="#0FF" /> |
|
||||||
<GradientStop Offset="0.76" |
|
||||||
Color="#0F0" /> |
|
||||||
<GradientStop Offset="0.85" |
|
||||||
Color="#FF0" /> |
|
||||||
<GradientStop Offset="1" |
|
||||||
Color="#F00" /> |
|
||||||
</LinearGradientBrush> |
|
||||||
</Border.Background> |
|
||||||
</Border> |
|
||||||
<Grid x:Name="arrows" |
|
||||||
IsHitTestVisible="False" |
|
||||||
VerticalAlignment="Top" |
|
||||||
Margin="-5"> |
|
||||||
<Path HorizontalAlignment="Left" |
|
||||||
Data="M 0 0 L 5 5 L 0 10 Z" |
|
||||||
Fill="Black" /> |
|
||||||
<Path HorizontalAlignment="Right" |
|
||||||
Data="M 0 0 L -5 5 L 0 10 Z" |
|
||||||
Fill="Black" /> |
|
||||||
</Grid> |
|
||||||
</BrushEditor:Picker> |
|
||||||
</Border> |
|
||||||
|
|
||||||
<Border BorderBrush="Black" |
|
||||||
BorderThickness="1"> |
|
||||||
<BrushEditor:Picker Value="{Binding S, ElementName=this}" |
|
||||||
Marker="{Binding ElementName=point}" |
|
||||||
ClipToBounds="True"> |
|
||||||
<BrushEditor:Picker Orientation="Vertical" |
|
||||||
Value="{Binding V, ElementName=this}" |
|
||||||
Minimum="100" |
|
||||||
Maximum="0" |
|
||||||
Marker="{Binding ElementName=point}"> |
|
||||||
<Rectangle> |
|
||||||
<Rectangle.Fill> |
|
||||||
<LinearGradientBrush EndPoint="1 0"> |
|
||||||
<GradientStop Offset="0" |
|
||||||
Color="White" /> |
|
||||||
<GradientStop Offset="1" |
|
||||||
Color="{Binding HueColor, ElementName=this}" /> |
|
||||||
</LinearGradientBrush> |
|
||||||
</Rectangle.Fill> |
|
||||||
</Rectangle> |
|
||||||
<Rectangle> |
|
||||||
<Rectangle.Fill> |
|
||||||
<LinearGradientBrush EndPoint="0 1"> |
|
||||||
<GradientStop Offset="0" |
|
||||||
Color="#0000" /> |
|
||||||
<GradientStop Offset="1" |
|
||||||
Color="#F000" /> |
|
||||||
</LinearGradientBrush> |
|
||||||
</Rectangle.Fill> |
|
||||||
</Rectangle> |
|
||||||
<Grid x:Name="point" |
|
||||||
VerticalAlignment="Top" |
|
||||||
HorizontalAlignment="Left" |
|
||||||
Width="12" |
|
||||||
Height="12" |
|
||||||
Margin="-6 -6 0 0"> |
|
||||||
<Ellipse Stroke="Black" |
|
||||||
IsHitTestVisible="False" /> |
|
||||||
<Ellipse Stroke="White" |
|
||||||
Margin="1" |
|
||||||
IsHitTestVisible="False" /> |
|
||||||
</Grid> |
|
||||||
</BrushEditor:Picker> |
|
||||||
</BrushEditor:Picker> |
|
||||||
</Border> |
|
||||||
|
|
||||||
</DockPanel> |
|
||||||
|
|
||||||
</UserControl> |
|
||||||
@ -1,184 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.ComponentModel; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor |
|
||||||
{ |
|
||||||
public partial class ColorPicker |
|
||||||
{ |
|
||||||
public ColorPicker() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty ColorProperty = |
|
||||||
DependencyProperty.Register("Color", typeof(Color), typeof(ColorPicker), |
|
||||||
new FrameworkPropertyMetadata(new Color(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); |
|
||||||
|
|
||||||
public Color Color { |
|
||||||
get { return (Color)GetValue(ColorProperty); } |
|
||||||
set { SetValue(ColorProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty HProperty = |
|
||||||
DependencyProperty.Register("H", typeof(int), typeof(ColorPicker)); |
|
||||||
|
|
||||||
public int H { |
|
||||||
get { return (int)GetValue(HProperty); } |
|
||||||
set { SetValue(HProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty SProperty = |
|
||||||
DependencyProperty.Register("S", typeof(int), typeof(ColorPicker)); |
|
||||||
|
|
||||||
public int S { |
|
||||||
get { return (int)GetValue(SProperty); } |
|
||||||
set { SetValue(SProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty VProperty = |
|
||||||
DependencyProperty.Register("V", typeof(int), typeof(ColorPicker)); |
|
||||||
|
|
||||||
public int V { |
|
||||||
get { return (int)GetValue(VProperty); } |
|
||||||
set { SetValue(VProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty RProperty = |
|
||||||
DependencyProperty.Register("R", typeof(byte), typeof(ColorPicker)); |
|
||||||
|
|
||||||
public byte R { |
|
||||||
get { return (byte)GetValue(RProperty); } |
|
||||||
set { SetValue(RProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty GProperty = |
|
||||||
DependencyProperty.Register("G", typeof(byte), typeof(ColorPicker)); |
|
||||||
|
|
||||||
public byte G { |
|
||||||
get { return (byte)GetValue(GProperty); } |
|
||||||
set { SetValue(GProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty BProperty = |
|
||||||
DependencyProperty.Register("B", typeof(byte), typeof(ColorPicker)); |
|
||||||
|
|
||||||
public byte B { |
|
||||||
get { return (byte)GetValue(BProperty); } |
|
||||||
set { SetValue(BProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty AProperty = |
|
||||||
DependencyProperty.Register("A", typeof(byte), typeof(ColorPicker)); |
|
||||||
|
|
||||||
public byte A { |
|
||||||
get { return (byte)GetValue(AProperty); } |
|
||||||
set { SetValue(AProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty HexProperty = |
|
||||||
DependencyProperty.Register("Hex", typeof(string), typeof(ColorPicker)); |
|
||||||
|
|
||||||
public string Hex { |
|
||||||
get { return (string)GetValue(HexProperty); } |
|
||||||
set { SetValue(HexProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty HueColorProperty = |
|
||||||
DependencyProperty.Register("HueColor", typeof(Color), typeof(ColorPicker)); |
|
||||||
|
|
||||||
public Color HueColor { |
|
||||||
get { return (Color)GetValue(HueColorProperty); } |
|
||||||
set { SetValue(HueColorProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
bool updating; |
|
||||||
|
|
||||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
base.OnPropertyChanged(e); |
|
||||||
|
|
||||||
if (updating) return; |
|
||||||
updating = true; |
|
||||||
|
|
||||||
if (e.Property == ColorProperty) { |
|
||||||
UpdateSource(ColorSource.Hsv); |
|
||||||
UpdateRest(ColorSource.Hsv); |
|
||||||
} |
|
||||||
else if (e.Property == HProperty || e.Property == SProperty || e.Property == VProperty) { |
|
||||||
var c = ColorHelper.ColorFromHsv(H, S / 100.0, V / 100.0); |
|
||||||
c.A = A; |
|
||||||
Color = c; |
|
||||||
UpdateRest(ColorSource.Hsv); |
|
||||||
} |
|
||||||
else if (e.Property == RProperty || e.Property == GProperty || e.Property == BProperty || e.Property == AProperty) { |
|
||||||
Color = Color.FromArgb(A, R, G, B); |
|
||||||
UpdateRest(ColorSource.Rgba); |
|
||||||
} |
|
||||||
else if (e.Property == HexProperty) { |
|
||||||
Color = ColorHelper.ColorFromString(Hex); |
|
||||||
UpdateRest(ColorSource.Hex); |
|
||||||
} |
|
||||||
|
|
||||||
updating = false; |
|
||||||
} |
|
||||||
|
|
||||||
void UpdateRest(ColorSource source) |
|
||||||
{ |
|
||||||
HueColor = ColorHelper.ColorFromHsv(H, 1, 1); |
|
||||||
UpdateSource((ColorSource)(((int)source + 1) % 3)); |
|
||||||
UpdateSource((ColorSource)(((int)source + 2) % 3)); |
|
||||||
} |
|
||||||
|
|
||||||
void UpdateSource(ColorSource source) |
|
||||||
{ |
|
||||||
if (source == ColorSource.Hsv) { |
|
||||||
double h, s, v; |
|
||||||
ColorHelper.HsvFromColor(Color, out h, out s, out v); |
|
||||||
|
|
||||||
H = (int)h; |
|
||||||
S = (int)(s * 100); |
|
||||||
V = (int)(v * 100); |
|
||||||
} |
|
||||||
else if (source == ColorSource.Rgba) { |
|
||||||
R = Color.R; |
|
||||||
G = Color.G; |
|
||||||
B = Color.B; |
|
||||||
A = Color.A; |
|
||||||
} |
|
||||||
else { |
|
||||||
Hex = ColorHelper.StringFromColor(Color); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
enum ColorSource |
|
||||||
{ |
|
||||||
Hsv, Rgba, Hex |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class HexTextBox : TextBox |
|
||||||
{ |
|
||||||
protected override void OnKeyDown(KeyEventArgs e) |
|
||||||
{ |
|
||||||
if (e.Key == Key.Enter) { |
|
||||||
var b = BindingOperations.GetBindingExpressionBase(this, TextProperty); |
|
||||||
if (b != null) { |
|
||||||
b.UpdateTarget(); |
|
||||||
} |
|
||||||
SelectAll(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,12 +0,0 @@ |
|||||||
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor.GradientBrushEditor" |
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:BrushEditor="clr-namespace:ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor" |
|
||||||
> |
|
||||||
<DockPanel> |
|
||||||
<BrushEditor:GradientSlider x:Name="slider" |
|
||||||
DockPanel.Dock="Top" |
|
||||||
Brush="{Binding Brush}" /> |
|
||||||
<BrushEditor:SolidBrushEditor Color="{Binding SelectedStop.Color, ElementName=slider}" /> |
|
||||||
</DockPanel> |
|
||||||
</UserControl> |
|
||||||
@ -1,24 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor |
|
||||||
{ |
|
||||||
public partial class GradientBrushEditor |
|
||||||
{ |
|
||||||
public GradientBrushEditor() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,109 +0,0 @@ |
|||||||
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor.GradientSlider" |
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:BrushEditor="clr-namespace:ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor" |
|
||||||
x:Name="this" |
|
||||||
> |
|
||||||
<UserControl.Resources> |
|
||||||
|
|
||||||
<DataTemplate x:Key="GradientStopTemplate"> |
|
||||||
<Grid> |
|
||||||
<Path x:Name="thumb" |
|
||||||
Data="m 6 0 l 6 5 v 12 h -12 v -12 z" |
|
||||||
Stroke="Black" |
|
||||||
Fill="Orange" /> |
|
||||||
<Border Margin="2 7 2 2" |
|
||||||
BorderBrush="Black" |
|
||||||
BorderThickness="1"> |
|
||||||
<Border BorderBrush="White" |
|
||||||
BorderThickness="1"> |
|
||||||
<Border.Background> |
|
||||||
<SolidColorBrush Color="red" /> |
|
||||||
</Border.Background> |
|
||||||
</Border> |
|
||||||
</Border> |
|
||||||
</Grid> |
|
||||||
<DataTemplate.Triggers> |
|
||||||
<Trigger Property="Selector.IsSelected" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="thumb" |
|
||||||
Property="Fill" |
|
||||||
Value="Gold" /> |
|
||||||
</Trigger> |
|
||||||
</DataTemplate.Triggers> |
|
||||||
</DataTemplate> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type BrushEditor:GradientThumb}"> |
|
||||||
<Setter Property="BrushEditor:NormalizedPanel.X" |
|
||||||
Value="{Binding Offset}" /> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type BrushEditor:GradientThumb}"> |
|
||||||
<StackPanel> |
|
||||||
<Path x:Name="thumb" |
|
||||||
Data="m 0 0 l 6 -5 l 6 5" |
|
||||||
Stroke="Black" |
|
||||||
Fill="White" /> |
|
||||||
<Border BorderBrush="Black" |
|
||||||
BorderThickness="1" |
|
||||||
Width="12" |
|
||||||
Height="12"> |
|
||||||
<Border BorderBrush="White" |
|
||||||
BorderThickness="1"> |
|
||||||
<Border.Background> |
|
||||||
<SolidColorBrush Color="{Binding Color}" /> |
|
||||||
</Border.Background> |
|
||||||
</Border> |
|
||||||
</Border> |
|
||||||
</StackPanel> |
|
||||||
<ControlTemplate.Triggers> |
|
||||||
<Trigger Property="Selector.IsSelected" |
|
||||||
Value="True"> |
|
||||||
<Setter TargetName="thumb" |
|
||||||
Property="Fill" |
|
||||||
Value="Orange" /> |
|
||||||
</Trigger> |
|
||||||
</ControlTemplate.Triggers> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
<Style TargetType="{x:Type BrushEditor:Dragger}"> |
|
||||||
<Setter Property="Template"> |
|
||||||
<Setter.Value> |
|
||||||
<ControlTemplate TargetType="{x:Type BrushEditor:Dragger}"> |
|
||||||
<Border BorderBrush="{TemplateBinding BorderBrush}" |
|
||||||
BorderThickness="{TemplateBinding BorderThickness}" |
|
||||||
Background="{TemplateBinding Background}" /> |
|
||||||
</ControlTemplate> |
|
||||||
</Setter.Value> |
|
||||||
</Setter> |
|
||||||
</Style> |
|
||||||
|
|
||||||
</UserControl.Resources> |
|
||||||
|
|
||||||
<Grid> |
|
||||||
<BrushEditor:Dragger x:Name="strip" |
|
||||||
BorderBrush="Black" |
|
||||||
BorderThickness="1" |
|
||||||
VerticalAlignment="Top" |
|
||||||
Height="20" |
|
||||||
Margin="6 0 6 0"> |
|
||||||
<Control.Background> |
|
||||||
<LinearGradientBrush EndPoint="1 0" |
|
||||||
GradientStops="{Binding Brush.GradientStops, ElementName=this}" /> |
|
||||||
</Control.Background> |
|
||||||
</BrushEditor:Dragger> |
|
||||||
<BrushEditor:GradientItemsControl x:Name="itemsControl" |
|
||||||
ItemsSource="{Binding GradientStops, ElementName=this}" |
|
||||||
Margin="6 28 6 10"> |
|
||||||
<ItemsControl.ItemsPanel> |
|
||||||
<ItemsPanelTemplate> |
|
||||||
<BrushEditor:NormalizedPanel /> |
|
||||||
</ItemsPanelTemplate> |
|
||||||
</ItemsControl.ItemsPanel> |
|
||||||
</BrushEditor:GradientItemsControl> |
|
||||||
</Grid> |
|
||||||
|
|
||||||
</UserControl> |
|
||||||
@ -1,159 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
using System.ComponentModel; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor |
|
||||||
{ |
|
||||||
public partial class GradientSlider |
|
||||||
{ |
|
||||||
public GradientSlider() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
|
|
||||||
BindingOperations.SetBinding(this, SelectedStopProperty, new Binding("SelectedItem") { |
|
||||||
Source = itemsControl, |
|
||||||
Mode = BindingMode.TwoWay |
|
||||||
}); |
|
||||||
|
|
||||||
strip.DragStarted += new DragStartedEventHandler(strip_DragStarted); |
|
||||||
strip.DragDelta += new DragDeltaEventHandler(strip_DragDelta); |
|
||||||
} |
|
||||||
|
|
||||||
static GradientSlider() |
|
||||||
{ |
|
||||||
EventManager.RegisterClassHandler(typeof(GradientSlider), |
|
||||||
Thumb.DragDeltaEvent, new DragDeltaEventHandler(ClassDragDelta)); |
|
||||||
} |
|
||||||
|
|
||||||
GradientStop newStop; |
|
||||||
double startOffset; |
|
||||||
|
|
||||||
public static readonly DependencyProperty BrushProperty = |
|
||||||
DependencyProperty.Register("Brush", typeof(GradientBrush), typeof(GradientSlider)); |
|
||||||
|
|
||||||
public GradientBrush Brush { |
|
||||||
get { return (GradientBrush)GetValue(BrushProperty); } |
|
||||||
set { SetValue(BrushProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty SelectedStopProperty = |
|
||||||
DependencyProperty.Register("SelectedStop", typeof(GradientStop), typeof(GradientSlider)); |
|
||||||
|
|
||||||
public GradientStop SelectedStop { |
|
||||||
get { return (GradientStop)GetValue(SelectedStopProperty); } |
|
||||||
set { SetValue(SelectedStopProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty GradientStopsProperty = |
|
||||||
DependencyProperty.Register("GradientStops", typeof(BindingList<GradientStop>), typeof(GradientSlider)); |
|
||||||
|
|
||||||
public BindingList<GradientStop> GradientStops { |
|
||||||
get { return (BindingList<GradientStop>)GetValue(GradientStopsProperty); } |
|
||||||
set { SetValue(GradientStopsProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static Color GetColorAtOffset(IList<GradientStop> stops, double offset) |
|
||||||
{ |
|
||||||
GradientStop s1 = stops[0], s2 = stops.Last(); |
|
||||||
foreach (var item in stops) { |
|
||||||
if (item.Offset < offset && item.Offset > s1.Offset) s1 = item; |
|
||||||
if (item.Offset > offset && item.Offset < s2.Offset) s2 = item; |
|
||||||
} |
|
||||||
return Color.FromArgb( |
|
||||||
(byte)((s1.Color.A + s2.Color.A) / 2), |
|
||||||
(byte)((s1.Color.R + s2.Color.R) / 2), |
|
||||||
(byte)((s1.Color.G + s2.Color.G) / 2), |
|
||||||
(byte)((s1.Color.B + s2.Color.B) / 2) |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
static void ClassDragDelta(object sender, DragDeltaEventArgs e) |
|
||||||
{ |
|
||||||
(sender as GradientSlider).thumb_DragDelta(sender, e); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
base.OnPropertyChanged(e); |
|
||||||
|
|
||||||
if (e.Property == BrushProperty) { |
|
||||||
if (Brush != null) { |
|
||||||
GradientStops = new BindingList<GradientStop>(Brush.GradientStops); |
|
||||||
SelectedStop = GradientStops.FirstOrDefault(); |
|
||||||
} |
|
||||||
else { |
|
||||||
GradientStops = null; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void strip_DragStarted(object sender, DragStartedEventArgs e) |
|
||||||
{ |
|
||||||
startOffset = e.HorizontalOffset / strip.ActualWidth; |
|
||||||
newStop = new GradientStop(GetColorAtOffset(GradientStops, startOffset), startOffset); |
|
||||||
GradientStops.Add(newStop); |
|
||||||
SelectedStop = newStop; |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
|
|
||||||
void strip_DragDelta(object sender, DragDeltaEventArgs e) |
|
||||||
{ |
|
||||||
MoveStop(newStop, startOffset, e); |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
|
|
||||||
void thumb_DragDelta(object sender, DragDeltaEventArgs e) |
|
||||||
{ |
|
||||||
var stop = (e.OriginalSource as GradientThumb).GradientStop; |
|
||||||
MoveStop(stop, stop.Offset, e); |
|
||||||
} |
|
||||||
|
|
||||||
void MoveStop(GradientStop stop, double oldOffset, DragDeltaEventArgs e) |
|
||||||
{ |
|
||||||
if (e.VerticalChange > 50 && GradientStops.Count > 2) { |
|
||||||
GradientStops.Remove(stop); |
|
||||||
SelectedStop = GradientStops.FirstOrDefault(); |
|
||||||
return; |
|
||||||
} |
|
||||||
stop.Offset = (oldOffset + e.HorizontalChange / strip.ActualWidth).Coerce(0, 1); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class GradientItemsControl : Selector |
|
||||||
{ |
|
||||||
protected override DependencyObject GetContainerForItemOverride() |
|
||||||
{ |
|
||||||
return new GradientThumb(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class GradientThumb : Thumb |
|
||||||
{ |
|
||||||
public GradientStop GradientStop { |
|
||||||
get { return DataContext as GradientStop; } |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPreviewMouseDown(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
base.OnPreviewMouseDown(e); |
|
||||||
var itemsControl = ItemsControl.ItemsControlFromItemContainer(this) as GradientItemsControl; |
|
||||||
itemsControl.SelectedItem = GradientStop; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class Dragger : Thumb |
|
||||||
{ |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,68 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Controls; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor |
|
||||||
{ |
|
||||||
public class NormalizedPanel : Panel |
|
||||||
{ |
|
||||||
public static double GetX(DependencyObject obj) |
|
||||||
{ |
|
||||||
return (double)obj.GetValue(XProperty); |
|
||||||
} |
|
||||||
|
|
||||||
public static void SetX(DependencyObject obj, double value) |
|
||||||
{ |
|
||||||
obj.SetValue(XProperty, value); |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty XProperty = |
|
||||||
DependencyProperty.RegisterAttached("X", typeof(double), typeof(NormalizedPanel), |
|
||||||
new PropertyMetadata(OnPositioningChanged)); |
|
||||||
|
|
||||||
public static double GetY(DependencyObject obj) |
|
||||||
{ |
|
||||||
return (double)obj.GetValue(YProperty); |
|
||||||
} |
|
||||||
|
|
||||||
public static void SetY(DependencyObject obj, double value) |
|
||||||
{ |
|
||||||
obj.SetValue(YProperty, value); |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty YProperty = |
|
||||||
DependencyProperty.RegisterAttached("Y", typeof(double), typeof(NormalizedPanel), |
|
||||||
new PropertyMetadata(OnPositioningChanged)); |
|
||||||
|
|
||||||
static void OnPositioningChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
NormalizedPanel parent = VisualTreeHelper.GetParent(d) as NormalizedPanel; |
|
||||||
if (parent != null) { |
|
||||||
parent.InvalidateArrange(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override Size MeasureOverride(Size availableSize) |
|
||||||
{ |
|
||||||
foreach (UIElement item in Children) { |
|
||||||
item.Measure(availableSize); |
|
||||||
} |
|
||||||
return new Size(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override Size ArrangeOverride(Size finalSize) |
|
||||||
{ |
|
||||||
foreach (UIElement item in Children) { |
|
||||||
Rect r = new Rect(item.DesiredSize); |
|
||||||
r.X = GetX(item) * finalSize.Width - item.DesiredSize.Width / 2; |
|
||||||
r.Y = GetY(item) * finalSize.Height - item.DesiredSize.Height / 2; |
|
||||||
item.Arrange(r); |
|
||||||
} |
|
||||||
return finalSize; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,137 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows.Controls.Primitives; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Data; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor |
|
||||||
{ |
|
||||||
public class Picker : Grid |
|
||||||
{ |
|
||||||
public Picker() |
|
||||||
{ |
|
||||||
SizeChanged += delegate { UpdateValueOffset(); }; |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty MarkerProperty = |
|
||||||
DependencyProperty.Register("Marker", typeof(UIElement), typeof(Picker)); |
|
||||||
|
|
||||||
public UIElement Marker { |
|
||||||
get { return (UIElement)GetValue(MarkerProperty); } |
|
||||||
set { SetValue(MarkerProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty ValueProperty = |
|
||||||
DependencyProperty.Register("Value", typeof(double), typeof(Picker), |
|
||||||
new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); |
|
||||||
|
|
||||||
public double Value { |
|
||||||
get { return (double)GetValue(ValueProperty); } |
|
||||||
set { SetValue(ValueProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty ValueOffsetProperty = |
|
||||||
DependencyProperty.Register("ValueOffset", typeof(double), typeof(Picker)); |
|
||||||
|
|
||||||
public double ValueOffset { |
|
||||||
get { return (double)GetValue(ValueOffsetProperty); } |
|
||||||
set { SetValue(ValueOffsetProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty OrientationProperty = |
|
||||||
DependencyProperty.Register("Orientation", typeof(Orientation), typeof(Picker)); |
|
||||||
|
|
||||||
public Orientation Orientation { |
|
||||||
get { return (Orientation)GetValue(OrientationProperty); } |
|
||||||
set { SetValue(OrientationProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty MinimumProperty = |
|
||||||
DependencyProperty.Register("Minimum", typeof(double), typeof(Picker)); |
|
||||||
|
|
||||||
public double Minimum { |
|
||||||
get { return (double)GetValue(MinimumProperty); } |
|
||||||
set { SetValue(MinimumProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty MaximumProperty = |
|
||||||
DependencyProperty.Register("Maximum", typeof(double), typeof(Picker), |
|
||||||
new FrameworkPropertyMetadata(100.0)); |
|
||||||
|
|
||||||
public double Maximum { |
|
||||||
get { return (double)GetValue(MaximumProperty); } |
|
||||||
set { SetValue(MaximumProperty, value); } |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
base.OnPropertyChanged(e); |
|
||||||
|
|
||||||
if (e.Property == MarkerProperty) { |
|
||||||
TranslateTransform t = Marker.RenderTransform as TranslateTransform; |
|
||||||
if (t == null) { |
|
||||||
t = new TranslateTransform(); |
|
||||||
Marker.RenderTransform = t; |
|
||||||
} |
|
||||||
var property = Orientation == Orientation.Horizontal ? TranslateTransform.XProperty : TranslateTransform.YProperty; |
|
||||||
BindingOperations.SetBinding(t, property, new Binding("ValueOffset") { |
|
||||||
Source = this |
|
||||||
}); |
|
||||||
} |
|
||||||
else if (e.Property == ValueProperty) { |
|
||||||
UpdateValueOffset(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool isMouseDown; |
|
||||||
|
|
||||||
protected override void OnPreviewMouseDown(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
isMouseDown = true; |
|
||||||
CaptureMouse(); |
|
||||||
UpdateValue(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPreviewMouseMove(MouseEventArgs e) |
|
||||||
{ |
|
||||||
if (isMouseDown) { |
|
||||||
UpdateValue(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPreviewMouseUp(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
isMouseDown = false; |
|
||||||
ReleaseMouseCapture(); |
|
||||||
} |
|
||||||
|
|
||||||
void UpdateValue() |
|
||||||
{ |
|
||||||
Point p = Mouse.GetPosition(this); |
|
||||||
double length = 0, pos = 0; |
|
||||||
|
|
||||||
if (Orientation == Orientation.Horizontal) { |
|
||||||
length = ActualWidth; |
|
||||||
pos = p.X; |
|
||||||
} |
|
||||||
else { |
|
||||||
length = ActualHeight; |
|
||||||
pos = p.Y; |
|
||||||
} |
|
||||||
|
|
||||||
pos = Math.Max(0, Math.Min(length, pos)); |
|
||||||
Value = Minimum + (Maximum - Minimum) * pos / length; |
|
||||||
} |
|
||||||
|
|
||||||
void UpdateValueOffset() |
|
||||||
{ |
|
||||||
var length = Orientation == Orientation.Horizontal ? ActualWidth : ActualHeight; |
|
||||||
ValueOffset = length * (Value - Minimum) / (Maximum - Minimum); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,19 +0,0 @@ |
|||||||
<UserControl |
|
||||||
x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor.SolidBrushEditor" |
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:BrushEditor="clr-namespace:ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor" |
|
||||||
x:Name="this" |
|
||||||
Height="284" |
|
||||||
> |
|
||||||
<TabControl> |
|
||||||
<TabItem Header="Color Picker"> |
|
||||||
<BrushEditor:ColorPicker Color="{Binding Color, ElementName=this}" /> |
|
||||||
</TabItem> |
|
||||||
<TabItem Header="Color List"> |
|
||||||
<ListBox ItemsSource="{Binding AvailableColors}" |
|
||||||
SelectedValue="{Binding Color, ElementName=this}" |
|
||||||
SelectedValuePath="Brush.Color" /> |
|
||||||
</TabItem> |
|
||||||
</TabControl> |
|
||||||
</UserControl> |
|
||||||
@ -1,33 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor |
|
||||||
{ |
|
||||||
public partial class SolidBrushEditor |
|
||||||
{ |
|
||||||
public SolidBrushEditor() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly DependencyProperty ColorProperty = |
|
||||||
DependencyProperty.Register("Color", typeof(Color), typeof(SolidBrushEditor), |
|
||||||
new FrameworkPropertyMetadata(new Color(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); |
|
||||||
|
|
||||||
public Color Color { |
|
||||||
get { return (Color)GetValue(ColorProperty); } |
|
||||||
set { SetValue(ColorProperty, value); } |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,9 +0,0 @@ |
|||||||
<TextBox |
|
||||||
x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.EventEditor" |
|
||||||
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
BorderThickness="0" |
|
||||||
Background="{x:Null}" |
|
||||||
Text="{Binding Value, UpdateSourceTrigger=Explicit}" |
|
||||||
> |
|
||||||
</TextBox> |
|
||||||
@ -1,71 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using ICSharpCode.WpfDesign.PropertyGrid; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors |
|
||||||
{ |
|
||||||
[TypeEditor(typeof(MulticastDelegate))] |
|
||||||
public partial class EventEditor |
|
||||||
{ |
|
||||||
public EventEditor() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
} |
|
||||||
|
|
||||||
public PropertyNode PropertyNode { |
|
||||||
get { return DataContext as PropertyNode; } |
|
||||||
} |
|
||||||
|
|
||||||
public string ValueString { |
|
||||||
get { return (string)PropertyNode.Value ?? ""; } |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnKeyDown(KeyEventArgs e) |
|
||||||
{ |
|
||||||
if (e.Key == Key.Enter) { |
|
||||||
Commit(); |
|
||||||
} |
|
||||||
else if (e.Key == Key.Escape) { |
|
||||||
BindingOperations.GetBindingExpression(this, TextProperty).UpdateTarget(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseDoubleClick(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
Commit(); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e) |
|
||||||
{ |
|
||||||
if (PropertyNode != null && Text != ValueString) { |
|
||||||
Commit(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void Commit() |
|
||||||
{ |
|
||||||
if (Text != ValueString) { |
|
||||||
if (string.IsNullOrEmpty(Text)) { |
|
||||||
PropertyNode.Reset(); |
|
||||||
return; |
|
||||||
} |
|
||||||
PropertyNode.Value = Text; |
|
||||||
} |
|
||||||
IEventHandlerService s = PropertyNode.Services.GetService<IEventHandlerService>(); |
|
||||||
if (s != null) { |
|
||||||
s.CreateEventHandler(PropertyNode.FirstProperty); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,9 +0,0 @@ |
|||||||
<Controls:NumericUpDown x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.NumberEditor" |
|
||||||
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
xmlns:Controls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls" |
|
||||||
xmlns:Converters="clr-namespace:ICSharpCode.WpfDesign.Designer.Converters" |
|
||||||
BorderThickness="0" |
|
||||||
Background="{x:Null}" |
|
||||||
Value="{Binding Value, Converter={x:Static Converters:DummyConverter.Instance}}"> |
|
||||||
</Controls:NumericUpDown> |
|
||||||
@ -1,121 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using ICSharpCode.WpfDesign.PropertyGrid; |
|
||||||
using System.Reflection; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors |
|
||||||
{ |
|
||||||
[TypeEditor(typeof(byte))] |
|
||||||
[TypeEditor(typeof(sbyte))] |
|
||||||
[TypeEditor(typeof(decimal))] |
|
||||||
[TypeEditor(typeof(double))] |
|
||||||
[TypeEditor(typeof(float))] |
|
||||||
[TypeEditor(typeof(int))] |
|
||||||
[TypeEditor(typeof(uint))] |
|
||||||
[TypeEditor(typeof(long))] |
|
||||||
[TypeEditor(typeof(ulong))] |
|
||||||
[TypeEditor(typeof(short))] |
|
||||||
[TypeEditor(typeof(ushort))] |
|
||||||
public partial class NumberEditor |
|
||||||
{ |
|
||||||
static NumberEditor() |
|
||||||
{ |
|
||||||
minimums[typeof(byte)] = byte.MinValue; |
|
||||||
minimums[typeof(sbyte)] = sbyte.MinValue; |
|
||||||
minimums[typeof(decimal)] = (double)decimal.MinValue; |
|
||||||
minimums[typeof(double)] = double.MinValue; |
|
||||||
minimums[typeof(float)] = float.MinValue; |
|
||||||
minimums[typeof(int)] = int.MinValue; |
|
||||||
minimums[typeof(uint)] = uint.MinValue; |
|
||||||
minimums[typeof(long)] = long.MinValue; |
|
||||||
minimums[typeof(ulong)] = ulong.MinValue; |
|
||||||
minimums[typeof(short)] = short.MinValue; |
|
||||||
minimums[typeof(ushort)] = ushort.MinValue; |
|
||||||
|
|
||||||
maximums[typeof(byte)] = byte.MaxValue; |
|
||||||
maximums[typeof(sbyte)] = sbyte.MaxValue; |
|
||||||
maximums[typeof(decimal)] = (double)decimal.MaxValue; |
|
||||||
maximums[typeof(double)] = double.MaxValue; |
|
||||||
maximums[typeof(float)] = float.MaxValue; |
|
||||||
maximums[typeof(int)] = int.MaxValue; |
|
||||||
maximums[typeof(uint)] = uint.MaxValue; |
|
||||||
maximums[typeof(long)] = long.MaxValue; |
|
||||||
maximums[typeof(ulong)] = ulong.MaxValue; |
|
||||||
maximums[typeof(short)] = short.MaxValue; |
|
||||||
maximums[typeof(ushort)] = ushort.MaxValue; |
|
||||||
} |
|
||||||
|
|
||||||
public NumberEditor() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
DataContextChanged += new DependencyPropertyChangedEventHandler(NumberEditor_DataContextChanged); |
|
||||||
} |
|
||||||
|
|
||||||
static Dictionary<Type, double> minimums = new Dictionary<Type, double>(); |
|
||||||
static Dictionary<Type, double> maximums = new Dictionary<Type, double>(); |
|
||||||
|
|
||||||
public PropertyNode PropertyNode { |
|
||||||
get { return DataContext as PropertyNode; } |
|
||||||
} |
|
||||||
|
|
||||||
void NumberEditor_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) |
|
||||||
{ |
|
||||||
if (PropertyNode == null) return; |
|
||||||
var type = PropertyNode.FirstProperty.ReturnType; |
|
||||||
|
|
||||||
var range = Metadata.GetValueRange(PropertyNode.FirstProperty); |
|
||||||
if (range == null) { |
|
||||||
range = new NumberRange() { Min = 0, Max = double.MaxValue }; |
|
||||||
} |
|
||||||
|
|
||||||
if (range.Min == double.MinValue) { |
|
||||||
Minimum = minimums[type]; |
|
||||||
} |
|
||||||
else { |
|
||||||
Minimum = range.Min; |
|
||||||
} |
|
||||||
|
|
||||||
if (range.Max == double.MaxValue) { |
|
||||||
Maximum = maximums[type]; |
|
||||||
} |
|
||||||
else { |
|
||||||
Maximum = range.Max; |
|
||||||
} |
|
||||||
|
|
||||||
if (Minimum == 0 && Maximum == 1) { |
|
||||||
DecimalPlaces = 2; |
|
||||||
SmallChange = 0.01; |
|
||||||
LargeChange = 0.1; |
|
||||||
} |
|
||||||
else { |
|
||||||
ClearValue(DecimalPlacesProperty); |
|
||||||
ClearValue(SmallChangeProperty); |
|
||||||
ClearValue(LargeChangeProperty); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
ChangeGroup group; |
|
||||||
|
|
||||||
protected override void OnDragStarted() |
|
||||||
{ |
|
||||||
group = PropertyNode.FirstProperty.DesignItem.Context.OpenGroup("drag number", |
|
||||||
PropertyNode.Properties.Select(p => p.DesignItem).ToArray()); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnDragCompleted() |
|
||||||
{ |
|
||||||
group.Commit(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,25 +0,0 @@ |
|||||||
<ContextMenu x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.PropertyContextMenu" |
|
||||||
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation" |
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|
||||||
> |
|
||||||
|
|
||||||
<MenuItem Header="Reset" |
|
||||||
Click="Click_Reset" /> |
|
||||||
<MenuItem Header="Binding" |
|
||||||
Click="Click_Binding" /> |
|
||||||
<MenuItem Header="TODO:" |
|
||||||
IsEnabled="False" /> |
|
||||||
<MenuItem x:Name="uxStaticResource" |
|
||||||
Header="Static Resource"> |
|
||||||
<MenuItem Header="Resource1" /> |
|
||||||
<MenuItem Header="Resource2" /> |
|
||||||
<MenuItem Header="Resource3" /> |
|
||||||
</MenuItem> |
|
||||||
<MenuItem Header="Custom Expression..." |
|
||||||
Click="Click_CustomExpression"/> |
|
||||||
<MenuItem Header="Convert To Local Value" |
|
||||||
Click="Click_ConvertToLocalValue"/> |
|
||||||
<MenuItem Header="Save As Resource..." |
|
||||||
Click="Click_SaveAsResource"/> |
|
||||||
|
|
||||||
</ContextMenu> |
|
||||||
@ -1,51 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.Linq; |
|
||||||
using System.Text; |
|
||||||
using System.Windows; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Data; |
|
||||||
using System.Windows.Documents; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
using System.Windows.Navigation; |
|
||||||
using System.Windows.Shapes; |
|
||||||
using ICSharpCode.WpfDesign.PropertyGrid; |
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.PropertyGrid |
|
||||||
{ |
|
||||||
public partial class PropertyContextMenu |
|
||||||
{ |
|
||||||
public PropertyContextMenu() |
|
||||||
{ |
|
||||||
InitializeComponent(); |
|
||||||
} |
|
||||||
|
|
||||||
public PropertyNode PropertyNode { |
|
||||||
get { return DataContext as PropertyNode; } |
|
||||||
} |
|
||||||
|
|
||||||
void Click_Reset(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
PropertyNode.Reset(); |
|
||||||
} |
|
||||||
|
|
||||||
void Click_Binding(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
PropertyNode.CreateBinding(); |
|
||||||
} |
|
||||||
|
|
||||||
void Click_CustomExpression(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
void Click_ConvertToLocalValue(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
void Click_SaveAsResource(object sender, RoutedEventArgs e) |
|
||||||
{ |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue