#region License Information
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
/* HeuristicLab
* Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Threading;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.AvalonEdit.CodeCompletion {
///
/// Provides icons for code-completion.
///
public class CompletionImage {
#region Non-Entity Images
static readonly BitmapImage namespaceImage = LoadBitmap("NameSpace");
///
/// Gets the image for namespaces.
///
public static ImageSource NamespaceImage {
get { return namespaceImage; }
}
static BitmapImage LoadBitmap(string name) {
BitmapImage image = new BitmapImage(new Uri("pack://application:,,,/HeuristicLab.CodeEditor-3.4;component/LanguageFeatures/CodeCompletion/CSharp/CompletionData/Images/" + name + ".png"));
image.Freeze();
return image;
}
#endregion
#region Entity Images
static readonly CompletionImage imageClass = new CompletionImage("Class", false);
static readonly CompletionImage imageStruct = new CompletionImage("Struct", false);
static readonly CompletionImage imageInterface = new CompletionImage("Interface", false);
static readonly CompletionImage imageDelegate = new CompletionImage("Delegate", false);
static readonly CompletionImage imageEnum = new CompletionImage("Enum", false);
static readonly CompletionImage imageStaticClass = new CompletionImage("StaticClass", false);
/// Gets the image used for non-static classes.
public static CompletionImage Class { get { return imageClass; } }
/// Gets the image used for structs.
public static CompletionImage Struct { get { return imageStruct; } }
/// Gets the image used for interfaces.
public static CompletionImage Interface { get { return imageInterface; } }
/// Gets the image used for delegates.
public static CompletionImage Delegate { get { return imageDelegate; } }
/// Gets the image used for enums.
public static CompletionImage Enum { get { return imageEnum; } }
/// Gets the image used for modules/static classes.
public static CompletionImage StaticClass { get { return imageStaticClass; } }
static readonly CompletionImage imageField = new CompletionImage("Field", true);
static readonly CompletionImage imageFieldReadOnly = new CompletionImage("FieldReadOnly", true);
static readonly CompletionImage imageLiteral = new CompletionImage("Literal", false);
static readonly CompletionImage imageEnumValue = new CompletionImage("EnumValue", false);
static readonly CompletionImage imageTemplate = new CompletionImage("Template", false);
/// Gets the image used for non-static classes.
public static CompletionImage Field { get { return imageField; } }
/// Gets the image used for structs.
public static CompletionImage ReadOnlyField { get { return imageFieldReadOnly; } }
/// Gets the image used for constants.
public static CompletionImage Literal { get { return imageLiteral; } }
/// Gets the image used for enum values.
public static CompletionImage EnumValue { get { return imageEnumValue; } }
/// Gets the image used for templates.
public static CompletionImage Template { get { return imageTemplate; } }
static readonly CompletionImage imageMethod = new CompletionImage("Method", true);
static readonly CompletionImage imageConstructor = new CompletionImage("Constructor", true);
static readonly CompletionImage imageVirtualMethod = new CompletionImage("VirtualMethod", true);
static readonly CompletionImage imageOperator = new CompletionImage("Operator", false);
static readonly CompletionImage imageExtensionMethod = new CompletionImage("ExtensionMethod", true);
static readonly CompletionImage imagePInvokeMethod = new CompletionImage("PInvokeMethod", true);
static readonly CompletionImage imageProperty = new CompletionImage("Property", true);
static readonly CompletionImage imageIndexer = new CompletionImage("Indexer", true);
static readonly CompletionImage imageEvent = new CompletionImage("Event", true);
/// Gets the image used for methods.
public static CompletionImage Method { get { return imageMethod; } }
/// Gets the image used for constructos.
public static CompletionImage Constructor { get { return imageConstructor; } }
/// Gets the image used for virtual methods.
public static CompletionImage VirtualMethod { get { return imageVirtualMethod; } }
/// Gets the image used for operators.
public static CompletionImage Operator { get { return imageOperator; } }
/// Gets the image used for extension methods.
public static CompletionImage ExtensionMethod { get { return imageExtensionMethod; } }
/// Gets the image used for P/Invoke methods.
public static CompletionImage PInvokeMethod { get { return imagePInvokeMethod; } }
/// Gets the image used for properties.
public static CompletionImage Property { get { return imageProperty; } }
/// Gets the image used for indexers.
public static CompletionImage Indexer { get { return imageIndexer; } }
/// Gets the image used for events.
public static CompletionImage Event { get { return imageEvent; } }
///
/// Gets the CompletionImage instance for the specified entity.
/// Returns null when no image is available for the entity type.
///
public static CompletionImage GetCompletionImage(IEntity entity) {
if (entity == null)
throw new ArgumentNullException("entity");
switch (entity.SymbolKind) {
case SymbolKind.TypeDefinition:
return GetCompletionImageForType(((ITypeDefinition)entity).Kind, entity.IsStatic);
case SymbolKind.Field:
IField field = (IField)entity;
if (field.IsConst) {
if (field.DeclaringTypeDefinition != null && field.DeclaringTypeDefinition.Kind == TypeKind.Enum)
return imageEnumValue;
else
return imageLiteral;
}
return field.IsReadOnly ? imageFieldReadOnly : imageField;
case SymbolKind.Method:
IMethod method = (IMethod)entity;
if (method.IsExtensionMethod)
return imageExtensionMethod;
else
return method.IsOverridable ? imageVirtualMethod : imageMethod;
case SymbolKind.Property:
return imageProperty;
case SymbolKind.Indexer:
return imageIndexer;
case SymbolKind.Event:
return imageEvent;
case SymbolKind.Operator:
case SymbolKind.Destructor:
return imageOperator;
case SymbolKind.Constructor:
return imageConstructor;
default:
return null;
}
}
///
/// Gets the CompletionImage instance for the specified entity.
/// Returns null when no image is available for the entity type.
///
public static CompletionImage GetCompletionImage(IUnresolvedEntity entity) {
if (entity == null)
throw new ArgumentNullException("entity");
switch (entity.SymbolKind) {
case SymbolKind.TypeDefinition:
return GetCompletionImageForType(((IUnresolvedTypeDefinition)entity).Kind, entity.IsStatic);
case SymbolKind.Field:
IUnresolvedField field = (IUnresolvedField)entity;
if (field.IsConst) {
if (field.DeclaringTypeDefinition != null && field.DeclaringTypeDefinition.Kind == TypeKind.Enum)
return imageEnumValue;
else
return imageLiteral;
}
return field.IsReadOnly ? imageFieldReadOnly : imageField;
case SymbolKind.Method:
IUnresolvedMethod method = (IUnresolvedMethod)entity;
return method.IsOverridable ? imageVirtualMethod : imageMethod;
case SymbolKind.Property:
return imageProperty;
case SymbolKind.Indexer:
return imageIndexer;
case SymbolKind.Event:
return imageEvent;
case SymbolKind.Operator:
case SymbolKind.Destructor:
return imageOperator;
case SymbolKind.Constructor:
return imageConstructor;
default:
return null;
}
}
static CompletionImage GetCompletionImageForType(TypeKind typeKind, bool isStatic) {
switch (typeKind) {
case TypeKind.Interface:
return imageInterface;
case TypeKind.Struct:
case TypeKind.Void:
return imageStruct;
case TypeKind.Delegate:
return imageDelegate;
case TypeKind.Enum:
return imageEnum;
case TypeKind.Class:
return isStatic ? imageStaticClass : imageClass;
case TypeKind.Module:
return imageStaticClass;
default:
return null;
}
}
///
/// Gets the image for the specified entity.
/// Returns null when no image is available for the entity type.
///
public static ImageSource GetImage(IEntity entity) {
CompletionImage image = GetCompletionImage(entity);
if (image != null)
return image.GetImage(entity.Accessibility, entity.IsStatic);
else
return null;
}
///
/// Gets the image for the specified entity.
/// Returns null when no image is available for the entity type.
///
public static ImageSource GetImage(IUnresolvedEntity entity) {
CompletionImage image = GetCompletionImage(entity);
if (image != null)
return image.GetImage(entity.Accessibility, entity.IsStatic);
else
return null;
}
#endregion
#region Overlays
static readonly BitmapImage overlayStatic = LoadBitmap("OverlayStatic");
///
/// Gets the overlay image for the static modifier.
///
public ImageSource StaticOverlay { get { return overlayStatic; } }
const int AccessibilityOverlaysLength = 5;
static readonly BitmapImage[] accessibilityOverlays = new BitmapImage[AccessibilityOverlaysLength] {
null,
LoadBitmap("OverlayPrivate"),
LoadBitmap("OverlayProtected"),
LoadBitmap("OverlayInternal"),
LoadBitmap("OverlayProtectedInternal")
};
///
/// Gets an overlay image for the specified accessibility.
/// Returns null if no overlay exists (for example, public members don't use overlays).
///
public static ImageSource GetAccessibilityOverlay(Accessibility accessibility) {
return accessibilityOverlays[GetAccessibilityOverlayIndex(accessibility)];
}
static int GetAccessibilityOverlayIndex(Accessibility accessibility) {
switch (accessibility) {
case Accessibility.Private:
return 1;
case Accessibility.Protected:
return 2;
case Accessibility.Internal:
return 3;
case Accessibility.ProtectedOrInternal:
case Accessibility.ProtectedAndInternal:
return 4;
default:
return 0;
}
}
#endregion
#region Instance Members (add overlay to entity image)
readonly string imageName;
readonly bool showStaticOverlay;
private CompletionImage(string imageName, bool showStaticOverlay) {
this.imageName = imageName;
this.showStaticOverlay = showStaticOverlay;
}
ImageSource[] images = new ImageSource[2 * AccessibilityOverlaysLength];
// 0..N-1 = base image + accessibility overlay
// N..2N-1 = base image + static overlay + accessibility overlay
///
/// Gets the image without any overlays.
///
public ImageSource BaseImage {
get {
ImageSource image = images[0];
if (image == null) {
image = LoadBitmap(imageName);
Thread.MemoryBarrier();
images[0] = image;
}
return image;
}
}
///
/// Gets this image combined with the specified accessibility overlay.
///
public ImageSource GetImage(Accessibility accessibility, bool isStatic = false) {
int accessibilityIndex = GetAccessibilityOverlayIndex(accessibility);
int index;
if (isStatic && showStaticOverlay)
index = accessibilityOverlays.Length + accessibilityIndex;
else
index = accessibilityIndex;
if (index == 0)
return this.BaseImage;
ImageSource image = images[index];
if (image == null) {
DrawingGroup g = new DrawingGroup();
Rect iconRect = new Rect(0, 0, 16, 16);
g.Children.Add(new ImageDrawing(this.BaseImage, iconRect));
if (accessibilityOverlays[accessibilityIndex] != null)
g.Children.Add(new ImageDrawing(accessibilityOverlays[accessibilityIndex], iconRect));
image = new DrawingImage(g);
image.Freeze();
Thread.MemoryBarrier();
images[index] = image;
}
return image;
}
///
public override string ToString() {
return "[CompletionImage " + imageName + "]";
}
#endregion
}
}